Estou usando o Django e, de vez em quando, recebo este erro:
IntegrityError: o valor duplicado da chave viola a restrição exclusiva "myapp_mymodel_pkey"
DETALHE: A chave (id) = (1) já existe.
De fato, meu banco de dados Postgres possui um objeto myapp_mymodel com a chave primária 1.
Por que o Postgres tentaria usar essa chave primária novamente? Ou, é mais provável que meu aplicativo (ou o ORM do Django) esteja causando isso?
Esse problema ocorreu mais três vezes seguidas agora. O que eu descobri é que quando isso acontece ocorrer acontece uma ou mais vezes em uma fila para uma determinada tabela, em seguida, de novo não. Parece ocorrer em todas as tabelas antes de parar completamente por dias, ocorrendo por pelo menos um minuto por tabela quando ocorre e ocorre apenas de forma intermitente (nem todas as tabelas imediatamente).
O fato de esse erro ser tão intermitente (aconteceu apenas três vezes em duas semanas - nenhuma outra carga no banco de dados, apenas eu testando meu aplicativo) é o que me deixa tão cauteloso com um problema de baixo nível.
fonte
Respostas:
O PostgreSQL não tentará inserir valores duplicados por si só, é você (sua aplicação, ORM incluído) quem o faz.
Pode ser uma sequência que alimenta os valores do PK definido na posição errada e a tabela já contém o valor igual ao seu
nextval()
- ou simplesmente que seu aplicativo faz a coisa errada. O primeiro é fácil de corrigir:O segundo significa depuração.
O Django (ou qualquer outra estrutura popular) não redefine as seqüências por conta própria - caso contrário, teríamos perguntas semelhantes a cada dois dias.
fonte
max(id)
antes da conclusão da primeira consulta e resultar em ambos o mesmo resultado?Você provavelmente está tentando inserir uma linha em uma tabela para a qual o valor da sequência de colunas em série não é atualizado.
Considere a seguinte coluna na sua tabela, que é a chave primária definida pelo Django ORM para o postgres
Cujo valor padrão está definido como
A sequência é avaliada apenas quando o campo de identificação é definido como em branco. Mas isso é problema se já houver entradas na tabela.
A pergunta é por que essas entradas anteriores não acionaram a atualização da sequência? Isso ocorre porque o valor do ID foi fornecido explicitamente para todas as entradas anteriores.
No meu caso, essas entradas iniciais foram carregadas de equipamentos através de migrações.
Esse problema também pode ser complicado através de entradas personalizadas com valor aleatório de PK.
Diga por exemplo. Existem 10 entradas na sua tabela. Você faz uma entrada explícita com PK = 15. As próximas quatro inserções no código funcionariam perfeitamente, mas a quinta criaria uma exceção.
fonte
Acabei aqui com o mesmo erro, que ocorria raramente e era difícil de rastrear, porque não estava procurando por onde deveria.
A falha foi a repetição de JS, que estava fazendo o POST no servidor duas vezes! Portanto, às vezes vale a pena dar uma olhada não apenas nas visualizações e formulários do seu django (ou em qualquer outra estrutura da web), mas também no que acontece na parte frontal.
fonte
Sim, coisa estranha. No meu caso, algo aparentemente errado durante o carregamento de dados nas migrações. Adicionei migração vazia e escrevi as linhas para adicionar alguns dados iniciais, 6 registros no meu caso.
Então, no painel de administração, tentei adicionar um novo item e obtive:
Primeira tentativa:
Tentativas posteriores:
E, finalmente, o sétimo e tempos são todos bem-sucedidos
Estou dizendo que talvez algo relacionado a bulk_create tenha carregado 6 itens lá. Talvez seja algo semelhante no seu projeto Django causando isso.
Django 1.9 PostgreSQL 9.3.14
fonte