Saya menggunakan Django, dan sesekali saya mendapatkan kesalahan ini:
IntegrityError: nilai kunci duplikat melanggar batasan unik "myapp_mymodel_pkey"
DETAIL: Kunci (id) = (1) sudah ada.
Database Postgres saya sebenarnya memiliki objek myapp_mymodel dengan kunci utama 1.
Mengapa Postgres mencoba menggunakan kunci utama itu lagi? Atau, apakah ini kemungkinan besar aplikasi saya (atau ORANG Django) yang menyebabkan ini?
Masalah ini terjadi 3 kali berturut-turut sekarang. Apa yang saya temukan adalah bahwa ketika tidak terjadi hal itu terjadi satu kali atau lebih berturut-turut untuk tabel tertentu, kemudian tidak lagi. Tampaknya terjadi untuk setiap tabel sebelum benar-benar berhenti selama berhari-hari, terjadi selama setidaknya satu menit atau lebih per tabel ketika itu terjadi, dan hanya terjadi sebentar-sebentar (tidak semua tabel segera).
Fakta bahwa kesalahan ini sangat terputus-putus (terjadi hanya 3 kali atau lebih dalam 2 minggu - tidak ada beban lain pada DB, hanya saya menguji aplikasi saya) adalah apa yang membuat saya sangat waspada terhadap masalah tingkat rendah.
sumber
Jawaban:
PostgreSQL tidak akan mencoba untuk memasukkan nilai duplikat sendiri, itu adalah Anda (aplikasi Anda, termasuk ORM) yang melakukannya.
Ini bisa berupa urutan yang memberi nilai ke PK yang disetel ke posisi yang salah dan tabel sudah berisi nilai yang sama dengan itu
nextval()
- atau hanya bahwa aplikasi Anda melakukan hal yang salah. Yang pertama mudah diperbaiki:Yang kedua berarti debugging.
Django (atau kerangka kerja populer lainnya) tidak mengatur ulang urutannya sendiri - jika tidak kita akan memiliki pertanyaan serupa setiap hari.
sumber
max(id)
sebelum kueri pertama selesai, dan kemudian menghasilkan keduanya memiliki hasil yang sama?Anda kemungkinan besar mengikat untuk memasukkan baris dalam tabel yang nilai urutan kolom serialnya tidak diperbarui.
Pertimbangkan kolom berikut di tabel Anda yang merupakan kunci utama yang didefinisikan oleh Django ORM untuk postgres
Nilai default siapa yang diatur
Urutan hanya dievaluasi ketika bidang id disetel sebagai kosong. Tapi itu masalah jika sudah ada entri ke dalam tabel.
Pertanyaannya adalah mengapa entri sebelumnya tidak memicu pembaruan urutan? Itu karena nilai id secara eksplisit disediakan untuk semua entri sebelumnya.
Dalam kasus saya, entri awal dimuat dari perlengkapan melalui migrasi.
Masalah ini juga dapat menjadi rumit melalui entri khusus dengan nilai PK acak.
Katakan misalnya. Ada 10 entri ke meja Anda. Anda membuat entri eksplisit dengan PK = 15. Empat sisipan berikutnya melalui kode akan bekerja dengan baik tetapi yang ke-5 akan memunculkan pengecualian.
sumber
Saya berakhir di sini dengan kesalahan yang sama, yang jarang terjadi, dan sulit dilacak, karena saya tidak mencarinya di tempat yang seharusnya.
Kesalahan adalah pengulangan JS yang melakukan POST ke server dua kali! Jadi kadang-kadang patut untuk melihat tidak hanya pada django Anda (atau kerangka kerja web lainnya) tetapi juga apa yang terjadi di sisi paling depan.
sumber
Ya hal yang aneh. Dalam kasus saya, ada sesuatu yang salah ketika memuat data dalam migrasi. Saya menambahkan migrasi kosong dan menulis baris untuk menambahkan beberapa data awal, 6 catatan dalam kasus saya.
Kemudian di panel admin saya mencoba menambahkan item baru dan mendapatkan:
Percobaan pertama:
Upaya selanjutnya:
Dan akhirnya yang ke 7 dan seterusnya semuanya sukses
Jadi saya katakan mungkin ada sesuatu yang berhubungan dengan bulk_create ketika saya memuat 6 item di sana. Ini mungkin sesuatu yang serupa dalam proyek Django Anda yang menyebabkan hal itu.
Django 1.9 PostgreSQL 9.3.14
sumber