Estoy usando Django, y de vez en cuando aparece este error:
IntegrityError: el valor duplicado de la clave viola la restricción única "myapp_mymodel_pkey"
DETALLE: La clave (id) = (1) ya existe.
De hecho, mi base de datos Postgres tiene un objeto myapp_mymodel con la clave primaria de 1.
¿Por qué Postgres intentaría usar esa clave primaria nuevamente? ¿O es muy probable que mi aplicación (o el ORM de Django) esté causando esto?
Este problema ocurrió 3 veces más seguidas en este momento. Lo que he encontrado es que cuando no se producen ocurre una o más veces en una fila de una tabla dada, a continuación, otra vez no. Parece suceder para cada mesa antes de que se detenga por completo durante días, ocurriendo durante al menos un minuto más o menos por mesa cuando ocurre, y solo sucede de manera intermitente (no todas las tablas de inmediato).
El hecho de que este error sea tan intermitente (sucedió solo 3 o más veces en 2 semanas; ninguna otra carga en el DB, solo yo probando mi aplicación) es lo que me hace desconfiar de un problema de bajo nivel.
fuente
Respuestas:
PostgreSQL no intentará insertar valores duplicados por sí solo, es usted (su aplicación, ORM incluido) quien lo hace.
Puede ser una secuencia que alimenta los valores al PK establecido en la posición incorrecta y la tabla que ya contiene el valor igual a su
nextval()
, o simplemente que su aplicación hace lo incorrecto. El primero es fácil de arreglar:El segundo significa depuración.
Django (o cualquier otro marco popular) no restablece las secuencias por sí solo; de lo contrario, tendríamos preguntas similares cada dos días.
fuente
max(id)
antes de que se complete la primera consulta, y luego dar como resultado que ambos tengan el mismo resultado?Lo más probable es que intente insertar una fila en una tabla para la cual el valor de secuencia de la columna serial no se actualiza.
Considere la siguiente columna en su tabla, que es la clave principal definida por Django ORM para postgres
Cuyo valor predeterminado se establece en
La secuencia solo se evalúa cuando el campo id se establece como en blanco. Pero eso es un problema si ya hay entradas en la tabla.
La pregunta es ¿por qué esas entradas anteriores no activaron la actualización de secuencia? Esto se debe a que el valor de id se proporcionó explícitamente para todas las entradas anteriores.
En mi caso, esas entradas iniciales se cargaron desde accesorios a través de migraciones.
Este problema también puede ser complicado a través de entradas personalizadas con un valor PK aleatorio.
Digamos por ej. Hay 10 entradas en su tabla. Realiza una entrada explícita con PK = 15. Los siguientes cuatro insertos a través del código funcionarían perfectamente bien, pero el quinto generaría una excepción.
fuente
Terminé aquí con el mismo error, que ocurría raramente, y era difícil de rastrear, porque lo estaba buscando no donde debería.
¡La falla fue la repetición de JS que estaba haciendo la POST al servidor dos veces! Por lo tanto, a veces vale la pena echar un vistazo no solo a sus vistas y formularios de django (o cualquier otro marco web), sino también a lo que sucede en la parte frontal.
fuente
Si cosa rara. En mi caso, algo parece estar mal durante la carga de datos en las migraciones. Agregué una migración vacía y escribí las líneas para agregar algunos datos iniciales, 6 registros en mi caso.
Luego, en el panel de administración, intenté agregar un nuevo elemento y obtuve:
Primer intento:
Intentos posteriores:
Y finalmente el 7mo y los tiempos son exitosos
Así que estoy diciendo que quizás haya algo relacionado con bulk_create cuando cargué 6 elementos allí. Tal vez sea algo similar en su proyecto de Django que causa eso.
Django 1.9 PostgreSQL 9.3.14
fuente