2009-05-12 5 views
89

Tengo problemas para cargar los dispositivos Django en mi base de datos MySQL debido a conflictos de tipo de contenido. Primero probé vertido los datos sólo de mi aplicación como esta:Problemas con los tipos de contenido al cargar un dispositivo en Django

./manage.py dumpdata escola > fixture.json 

pero seguí recibiendo faltante problemas clave externa, porque mi aplicación "escola" utiliza las tablas de otras aplicaciones. Seguí añadiendo aplicaciones adicionales hasta que llegué a esto:

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

Ahora el problema es el siguiente violación de restricción cuando intento cargar los datos como un accesorio de la 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 de las claves primarias del dispositivo. 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 personalizados como se documenta aquí: http://docs.djangoproject.com/en/dev/ref/models/options/#permissions

Respuesta

33

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 utilizar la bandera --natural a dumpdata, como se ha señalado en una respuesta a continuación. Esa bandera aún no existía cuando escribí esta respuesta.

+3

yo estaba corriendo en esto también, la reposición de los ContentTypes aplicación trabajó para mí como bien. ¡Gracias por el consejo! – Beau

+0

¿Cómo los reinició? En la clase de caso de prueba? Dame un ejemplo, por favor –

+4

No uso accesorios para pruebas unitarias, generalmente creo datos de prueba usando el ORM en un método setup() porque es más fácil mantener la sincronización con las pruebas. Así que nunca tuve que hacer esto en una clase TestCase, aunque estoy seguro de que si hurgas en el código de la clase TestCase de Django, puedes averiguar cómo hacer un reinicio después de syncdb y antes de que se cargue el dispositivo en una subclase. Para mí, era solo "./manage.py reset contenttypes" en un script bash anterior a "./manage.py loaddata my_fixture". –

27

Trate de saltar al crear ContentTypes accesorio:

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

Se trabajó para mí en una situación similar para las pruebas unitarias, su visión con respecto a los ContentTypes realmente me ayudó!

10

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 con el comando manage.py y yo hacer lo mismo utilizando sólo 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 ContentTypes volcado de aplicación que corresponda al resto de los datos de prueba. Al restablecer la aplicación antes de cargarla, se evita la clave duplicada IntegrityError.

124

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

  • Permission.codename se utiliza en favor de Permission.id
  • User.username se utiliza en favor de User.id

Leer más: natural keys section in "serializing django objects"

Algunos otros argumentos útiles para dumpdata:

  • --indent=4 hacerlo legible para las personas.
  • -e sessions excluyen los datos de sesión
  • -e admin excluyen historial de las acciones admin el sitio de administración
  • -e contenttypes -e auth.Permission excluir los objetos que se vuelven a crear automáticamente a partir del esquema cada vez que durante syncdb. Solo úsela junto con --natural o de lo contrario podría terminar con números de identificación mal alineados.
+0

Estoy usando esto para obtener claves naturales para un atributo content_type, pero obtengo este error cuando intento cargar los dispositivos. TypeError: los índices de cadena deben ser enteros, no str ¿Alguna idea de por qué? – philgo20

+12

Esta es la solución correcta; aún no existía cuando publiqué mi respuesta. La respuesta aceptada debería cambiarse a esto, creo. –

+1

@skyjur ¿Por qué siempre usar '-e contenttypes -e auth.permission' con' --natural'? Lo intenté sin la opción '--natural' y funcionó. También la [documentación aquí] (https://docs.djangoproject.com/en/1.6/ref/django-admin/#django-admin-option---natural) dice que se debe usar esta opción si ** DUMPING ** 'auth.permission' y' contenttypes'. – wlnirvana

1

Voy a dar otra respuesta posible que acabo de descifrar. 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 claves externas coinciden con otra entrada que ya está en la tabla con un diferente pk, fallará. Las tablas de relaciones M2M tienen un "conjunto único" para las dos claves externas.

Por lo tanto, si se trata de una relación M2M que se está rompiendo, observe las claves externas que está agregando, observe su base de datos para ver si ese par de FK ya figura en una PK diferente.

1

Es realmente, realmente molesto ... Me pican por esto cada vez.

Me trataron de DumpData con ContentTypes --exclude y --natural, siempre me dan problemas ..

Lo que funciona mejor para mí es simplemente hacer un truncate table django_content_type; después de la syncdb y luego cargar los datos.

Por supuesto para la carga automática initial_data.json eres fallball.

+0

Para mí, truncar la tabla antes de cargar datos solo causa diferentes errores. Sin suerte con esta técnica. – shacker

1

A veces he encontrado 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

9

no estaba usando MySQL, pero en lugar de importar algunos datos de un servidor activo en SQLite. Eliminación de los datos de aplicaciones contenttypes antes de realizar loaddata hizo el truco:

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

Y luego

python manage.py loaddata data.json 
11

Las respuestas aquí toda la vieja ...A partir de 2017, la mejor respuesta es:

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

Gracias Esto resolvió mi problema ... Esta es la mejor solución –

2
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 ha creado, puede excluirlos con seguridad. Una desventaja de este enfoque es que pierde los datos de registro así como los datos de autenticación.
0
./manage.py dumpdata app.Model --natural-foreign 

cambiará

"content_type": 123 

a

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

Y accesorio funciona para TestCase ahora

Cuestiones relacionadas