Problemas con los tipos de contenido al cargar un dispositivo en Django

Tengo problemas para cargar accesorios Django en mi base de datos MySQL debido a conflictos de tipos de contenido. Primero intenté eliminar los datos solo de mi aplicación de esta manera:

./manage.py dumpdata escola > fixture.json 

pero seguí perdiendo problemas de claves externas, porque mi aplicación “escola” usa tablas de otras aplicaciones. Seguí agregando aplicaciones adicionales hasta que llegué a esto:

 ./manage.py dumpdata contenttypes auth escola > fixture.json 

Ahora el problema es la siguiente violación de restricción cuando bash cargar los datos como un accesorio de prueba:

 IntegrityError: (1062, "Duplicate entry 'escola-t23aluno' for key 2") 

Parece que el problema es que Django está intentando recrear dinámicamente los tipos de contenido con diferentes valores de clave primaria que entran en conflicto con los valores clave primarios del accesorio. Esto parece ser el mismo que el error documentado aquí: http://code.djangoproject.com/ticket/7052

El problema es que la solución recomendada es volcar la aplicación contenttypes que ya estoy haciendo? ¿Lo que da? Si hace alguna diferencia, tengo algunos permisos de modelo personalizado como se documenta aquí: http://docs.djangoproject.com/en/dev/ref/models/options/#permissions

manage.py dumpdata --natural usará una representación más duradera de claves externas. En django se les llama “llaves naturales”. Por ejemplo:

  • Permission.codename se utiliza a favor de Permission.id
  • User.username se usa a favor de User.id

Leer más: sección de claves naturales en “serialización de objetos django”

Algunos otros argumentos útiles para dumpdata :

  • --indent=4 hacen legible para los humanos.
  • -e sessions excluyen datos de sesión
  • -e admin excluye el historial de acciones de administrador en el sitio de administración
  • -e contenttypes -e auth.Permission excluye objetos que se -e contenttypes -e auth.Permission crear automáticamente desde el esquema cada vez durante syncdb . Solo --natural junto con --natural o de lo contrario podría terminar con números de identificación mal alineados.

Sí, esto es realmente irritante. Durante un tiempo trabajé en ello haciendo un “reinicio de manage.py” en la aplicación contenttypes antes de cargar el dispositivo (para eliminar los datos de tipo de contenido generados automáticamente que diferían de la versión objeto de dumping). Eso funcionó, pero finalmente me cansé de las molestias y los accesorios abandonados totalmente a favor de los volcados directos de SQL (por supuesto, entonces pierdes la portabilidad DB).

actualización : la mejor respuesta es usar el indicador dumpdata a dumpdata , como se indica en la respuesta a continuación. Esa bandera aún no existía cuando escribí esta respuesta.

Intente omitir los tipos de contenido al crear el accesorio:

 ./manage.py dumpdata --exclude contenttypes > fixture.json 

Me funcionó en una situación similar para las pruebas unitarias, ¡tu percepción sobre los tipos de contenido realmente ayudó!

Las respuestas aquí son todas viejas … A partir de 2017, la mejor respuesta es:

 manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4 

He resuelto este problema en mis casos de prueba reiniciando la aplicación contenttypes de la prueba unitaria antes de cargar mi archivo de volcado. Carl sugirió que esto ya manage.py usando el comando manage.py y yo hago lo mismo solo con el método call_command :

 >>> from django.core import management >>> management.call_command("flush", verbosity=0, interactive=False) >>> management.call_command("reset", "contenttypes", verbosity=0, interactive=False) >>> management.call_command("loaddata", "full_test_data.json", verbosity=0) 

Mi accesorio full_test_data.json contiene el volcado de la aplicación full_test_data.json que corresponde al rest de los datos de prueba. Al restablecer la aplicación antes de cargarla, evita la clave duplicada IntegrityError .

No estaba usando MySQL, sino que importaba algunos datos de un servidor en vivo en sqlite. La loaddata datos de la aplicación loaddata antes de realizar loaddata hizo el truco:

 from django.contrib.contenttypes.models import ContentType ContentType.objects.all().delete() quit() 

Y entonces

 python manage.py loaddata data.json 
 python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json 

Esto funciona para mí Aquí estoy excluyendo todo bubt los modelos reales.

  • Si ve algún otro modelo que no sean los modelos que creó, puede excluirlos con seguridad. Una desventaja de este enfoque es que pierde los datos de registro así como los datos de autenticación.

Voy a dar otra respuesta posible que acabo de descubrir. Tal vez ayude al OP, quizás ayude a alguien más.

Tengo una tabla de relaciones de muchos a muchos. Tiene una clave principal y las dos claves externas a las otras tablas. Descubrí que si tengo una entrada en el dispositivo cuyas dos teclas externas coinciden con otra entrada que ya está en la tabla con un pk diferente , fallará. Las tablas de relaciones M2M tienen un “conjunto único” para las dos claves externas.

Entonces, si se trata de una relación M2M que se está rompiendo, fíjate en las claves externas que está agregando, mira en tu base de datos para ver si ese par de FK ya están en una PK diferente.

Es realmente, realmente molesto … Me muerde esto cada vez.

Intenté dumpdata con –excluir los tipos de contenido y –natural, siempre tengo problemas …

Lo que funciona mejor para mí es simplemente hacer una truncate table django_content_type; después del syncdb y ENTONCES carga los datos.

Por supuesto, para initial_data.json auto cargando eres una bola de nieve.

A veces me he encontrado con un error similar. Resultó que estaba intentando cargar los accesorios antes de crear las tablas necesarias. Así que lo hice:

 $ python manage.py makemigrations $ python manage.py migrate $ python manage.py loaddata fixtures/initial_data.json 

Y funcionó como un encanto

 ./manage.py dumpdata app.Model --natural-foreign 

cambiará

  "content_type": 123 

a

  "content_type": [ "app_label", "model" ], 

Y el accesorio funciona para TestCase ahora