Używam Django i od czasu do czasu pojawia się ten błąd:
IntegrityError: zduplikowana wartość klucza narusza unikalne ograniczenie „klucz_aplikacji_aplikacji”
SZCZEGÓŁ: Klucz (identyfikator) = (1) już istnieje.
Moja baza danych Postgres faktycznie ma obiekt myapp_mymodel z kluczem podstawowym 1.
Dlaczego Postgres ponownie próbowałby użyć tego klucza podstawowego? A może jest to prawdopodobnie spowodowane przez moją aplikację (lub ORM Django)?
Ten problem występował jeszcze 3 razy z rzędu. Co znalazłem to, że kiedy ma nastąpić zdarza się jeden lub więcej razy z rzędu dla danej tabeli, a następnie nie ponownie. Wydaje się, że dzieje się to na każdym stole, zanim całkowicie zatrzyma się na kilka dni, dzieje się przez co najmniej minutę na stole, kiedy to nastąpi, i dzieje się tylko z przerwami (nie wszystkie stoły od razu).
Fakt, że ten błąd jest tak nieregularny (zdarzało się tylko 3 razy w ciągu 2 tygodni - nie ma żadnego obciążenia DB, tylko ja testuję moją aplikację) sprawia, że jestem tak ostrożny wobec problemu niskiego poziomu.
źródło
Odpowiedzi:
PostgreSQL nie będzie próbował wstawiać zduplikowanych wartości samodzielnie, tylko Ty (Twoja aplikacja, w tym ORM).
Może to być sekwencja dostarczająca wartości do zestawu PK do niewłaściwej pozycji, a tabela już zawiera wartość równą jej
nextval()
- lub po prostu, że twoja aplikacja robi coś złego. Pierwszy jest łatwy do naprawienia:Drugi oznacza debugowanie.
Django (lub jakikolwiek inny popularny framework) nie resetuje sekwencji samodzielnie - w przeciwnym razie mielibyśmy podobne pytania co drugi dzień.
źródło
max(id)
przed zakończeniem pierwszego zapytania, a następnie powoduje, że oba mają ten sam wynik?Najprawdopodobniej chcesz wprowadzić wiersz do tabeli, dla której wartość sekwencji kolumny szeregowej nie jest aktualizowana.
Rozważ następującą kolumnę w tabeli, która jest kluczem podstawowym zdefiniowanym przez Django ORM dla postgres
Czyją wartością domyślną jest
Sekwencja jest oceniana tylko wtedy, gdy pole id jest ustawione jako puste. Jest to problem, jeśli w tabeli są już wpisy.
Pytanie, dlaczego te wcześniejsze wpisy nie spowodowały aktualizacji sekwencji? Wynika to z faktu, że wartość id została jawnie podana dla wszystkich wcześniejszych wpisów.
W moim przypadku te początkowe wpisy zostały załadowane z urządzeń poprzez migracje.
Ten problem może być również trudny dzięki niestandardowym wpisom z losową wartością PK.
Powiedz na przykład W Twojej tabeli znajduje się 10 pozycji. Dokonujesz wyraźnego wpisu z PK = 15. Następne cztery wstawki w kodzie działałyby idealnie, ale piąta spowodowałaby wyjątek.
źródło
Skończyło się na mnie z tym samym błędem, który zdarzał się rzadko i był trudny do wyśledzenia, ponieważ szukałem go nie tam, gdzie powinienem.
Usterką było powtórzenie JS, które dwukrotnie wykonało test POST na serwerze! Czasami więc warto przyjrzeć się nie tylko widokom i formularzom django (lub dowolnego innego frameworka), ale także temu, co dzieje się na pierwszej stronie.
źródło
Tak, dziwna rzecz. W moim przypadku coś najwyraźniej jest błędne podczas ładowania danych w migracji. Dodałem pustą migrację i napisałem wiersze, aby dodać trochę danych początkowych, w moim przypadku 6 rekordów .
Następnie w panelu administracyjnym próbowałem dodać nowy element i otrzymałem:
Pierwsze podejscie:
Późniejsze próby:
I wreszcie 7. i na czas wszystkie są udane
Mówię więc, że może coś związanego z bulk_create, gdy załadowałem tam 6 elementów. Może to być przyczyną podobnego problemu w projekcie Django.
Django 1.9 PostgreSQL 9.3.14
źródło