Je ne parviens pas à charger les appareils Django dans ma base de données MySQL en raison de conflits de types de contenu. J'ai d'abord essayé de vider les données de mon application comme ceci:
./manage.py dumpdata escola > fixture.json
mais des problèmes de clé étrangère me manquaient, car mon application "escola" utilise des tableaux d'autres applications. J'ai continué à ajouter des applications supplémentaires jusqu'à arriver à ceci:
./manage.py dumpdata contenttypes auth escola > fixture.json
Maintenant, le problème est la violation de contrainte suivante lorsque j'essaie de charger les données en tant que dispositif de test:
IntegrityError: (1062, "Duplicate entry 'escola-t23aluno' for key 2")
Il semble que le problème est que Django tente de recréer de manière dynamique des types de contenu avec différentes valeurs de clé primaire en conflit avec les valeurs de clé primaire du projecteur. Cela semble être le même que le bogue documenté ici: http://code.djangoproject.com/ticket/7052
Le problème est que la solution de contournement recommandée consiste à vider l'application contenttypes que je fais déjà!? Ce qui donne? Si cela fait une différence, j'ai des autorisations de modèle personnalisées décrites ici: http://docs.djangoproject.com/en/dev/ref/models/options/#permissions
manage.py dumpdata --natural
utilisera une représentation plus durable des clés étrangères. À Django, on les appelle "clés naturelles". Par exemple:
Permission.codename
est utilisé en faveur de Permission.id
User.username
est utilisé en faveur de User.id
En savoir plus: Section des clés naturelles dans "Sérialisation des objets Django"
Quelques autres arguments utiles pour dumpdata
:
--indent=4
le rendre lisible par l'homme.-e sessions
exclure les données de session-e admin
exclure l'historique des actions de l'administrateur sur le site de l'administrateur-e contenttypes -e auth.Permission
exclut les objets qui sont recréés automatiquement du schéma à chaque fois pendant syncdb
. Utilisez-le uniquement avec --natural
, sinon vous pourriez vous retrouver avec des identifiants mal alignés.Oui, c'est vraiment irritant. Pendant un certain temps, j'ai travaillé dessus en effectuant une "réinitialisation manage.py" sur l'application contenttypes avant de charger le projecteur (pour supprimer les données de type de contenu générées automatiquement qui différaient de la version exportée). Cela a fonctionné, mais finalement, j'en ai eu marre des tracas et des appareils abandonnés en faveur des dumps SQL droits (bien sûr, vous perdrez alors la portabilité de la base de données).
update - la meilleure réponse consiste à utiliser l'indicateur --natural
en dumpdata
, comme indiqué dans une réponse ci-dessous. Ce drapeau n'existait pas encore lorsque j'ai écrit cette réponse.
Essayez de sauter les types de contenu lors de la création d'un appareil:
./manage.py dumpdata --exclude contenttypes > fixture.json
Cela a fonctionné pour moi dans une situation similaire pour les tests unitaires, votre compréhension des types de contenu a vraiment aidé!
Les réponses ici toutes anciennes ... À partir de 2017, la meilleure réponse est:
manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4
J'ai résolu ce problème dans mes cas de test en réinitialisant l'application contenttypes à partir du test unitaire avant de charger mon fichier de vidage. Carl a déjà suggéré cela en utilisant la commande manage.py
et je fais la même chose en utilisant la méthode 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)
Mon appareil full_test_data.json
contient le dump de l'application contenttypes qui correspond au reste des données de test. En réinitialisant l'application avant le chargement, cela évite la duplication de la clé IntegrityError
.
Je n'utilisais pas MySQL, mais importais plutôt des données d'un serveur live dans sqlite. Effacer les données de l'application contenttypes
avant d'exécuter loaddata
a été efficace:
from Django.contrib.contenttypes.models import ContentType
ContentType.objects.all().delete()
quit()
Et alors
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
Cela fonctionne pour moi. Ici, tout est exclu des modèles actuels.
Je vais donner une autre réponse possible que je viens de comprendre. Peut-être que ça va aider le PO, peut-être que ça va aider quelqu'un d'autre.
J'ai une table de relation plusieurs à plusieurs. Il a une clé primaire et les deux clés étrangères des autres tables. J'ai constaté que si j'ai une entrée dans le dispositif dont les deux clés étrangères sont identiques à une autre entrée déjà dans la table avec un différent pk, cela échouera. Les tables de relations M2M ont un "ensemble unique" pour les deux clés étrangères.
Ainsi, si une relation M2M est en train de se rompre, examinez les clés étrangères qu’elle ajoute, examinez votre base de données pour voir si cette paire de FK figure déjà sous un autre PK.
./manage.py dumpdata app.Model --natural-foreign
changera
"content_type": 123
à
"content_type": [
"app_label",
"model"
],
Et le montage fonctionne pour TestCase
maintenant
J'avais rencontré une erreur similaire parfois auparavant. Il s'est avéré que j'essayais de charger les fixtures avant de créer les tables nécessaires. Alors j'ai fait:
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py loaddata fixtures/initial_data.json
Et ça a fonctionné comme un charme
C'est vraiment, vraiment énervant… Je me fais piquer à chaque fois.
J'ai essayé de dumpdata avec --exclude contenttypes et --natural, j'ai toujours des problèmes ..
Ce qui me convient le mieux est simplement de faire un truncate table Django_content_type;
après la synchronisation et de charger les données.
Bien sûr, pour initial_data.json, le chargement automatique est une erreur.
Vous devez utiliser des clés naturelles pour représenter toute clé étrangère et toute relation plusieurs à plusieurs. De plus, il peut être judicieux d'exclure la table session
de l'application sessions
et la table logentry
de l'application admin
.
Django 1.7+
python manage.py dumpdata --natural-foreign --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
Django <1.7
python manage.py dumpdata --natural --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
D'après la documentation Django , --natural
est obsolète dans la version 1.7, l'option --natural-foreign
doit donc être utilisée à la place.
Vous pouvez également omettre la clé primaire dans les données sérialisées de cet objet, car elle peut être calculée pendant la désérialisation en passant l'indicateur --natural-primary
.
python manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json