Je construis une application Django avec une base de données MySQL. Lorsque j'exécute 'python manage.py migrate' pour la première fois, certaines tables sont bien créées puis des erreurs apparaissent. L'erreur signalée est :
Django.db.utils.IntegrityError: (1215, 'Impossible d'ajouter une contrainte de clé étrangère')
Lorsque j'exécute cette commande MySQL -
AFFICHER LE STATUT INNODB DU MOTEUR\G,
Je reçois ceci >>>
2015-02-17 14:33:17 7f10891cf700 Error in foreign key constraint of table movie_store/#sql-4f1_66:
FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`):
Cannot resolve table name close to:
(`id`)
Le retraçage complet est:
Creating tables...
Creating table users
Creating table merchant
Creating table celery_taskmeta
Creating table celery_tasksetmeta
Creating table djcelery_intervalschedule
Creating table djcelery_crontabschedule
Creating table djcelery_periodictasks
Creating table djcelery_periodictask
Creating table djcelery_workerstate
Creating table djcelery_taskstate
Creating table post_office_email
Creating table post_office_log
Creating table post_office_emailtemplate
Creating table post_office_attachment
Running deferred SQL...
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/Django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/Django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/dist-packages/Django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python2.7/dist-packages/Django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/dist-packages/Django/core/management/commands/migrate.py", line 173, in handle
created_models = self.sync_apps(connection, executor.loader.unmigrated_apps)
File "/usr/local/lib/python2.7/dist-packages/Django/core/management/commands/migrate.py", line 309, in sync_apps
cursor.execute(statement)
File "/usr/local/lib/python2.7/dist-packages/Django/db/backends/utils.py", line 80, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/Django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/Django/db/utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/lib/python2.7/dist-packages/Django/db/backends/utils.py", line 63, in execute
return self.cursor.execute(sql)
File "/usr/local/lib/python2.7/dist-packages/Django/db/backends/mysql/base.py", line 124, in execute
return self.cursor.execute(query, args)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
Django.db.utils.IntegrityError: (1215, 'Cannot add foreign key constraint')
Cela fonctionnera
python manage.py migrate auth
python manage.py migrate
Le problème est dû à une autre migration exécutée avant l'authentification, donc cela garantira que la migration de "authtools" s'exécute en premier
Avez-vous créé des migrations pour toutes vos applications? Sinon, vous pourriez bien rencontrer le problème que les tables de base de données sont créées dans le mauvais ordre, ce qui vous donnera cette erreur.
Si vous avez un projet Django 1.7 existant, vous devez créer les fichiers de migration initiale, puis simuler la migration initiale, comme décrit ici
https://docs.djangoproject.com/en/1.8/topics/migrations/#adding-migrations-to-apps
Créez la migration avec
$ python manage.py make migrations your_app_label
Et puis simuler l'application
$ python manage.py migrate --fake-initial your_app_label
J'ai rencontré ce problème lorsque j'utilise:
$ python manage.py test
Si vous n'avez pas effectué de migrations pour ces modèles dont le champ est une clé étrangère vers Django.contrib. auth.models.User , cela causera ce problème.
Et si vous avez activé --keepdb
, Vous constaterez qu'il n'y a pas de table auth_user
Et une autre table d'administration de Django.
Trouvons tout le problème:
courir:
$ python manage.py test --verbosity=3
Vous pouvez voir l'exception de contrainte foreigngkey déclenchée après
Exécution de SQL différé ...
le sql différé est similaire à
"ALTER TABLE
xxx
ADD CONSTRAINTxx
FOREIGN KEY (x
) REFERENCESauth_user
"
vérifiez le code source de Django/core/management/commandes/migrate.py :
for statement in deferred_sql:
cursor.execute(statement)
Le defered_sql
Vient de la boucle manifest.items()
for,
et manifest
provient de all_models
,
et all_models
provient de app_config.label dans app_labels .
c'est l'argument passé par
self.sync_apps(connection, executor.loader.unmigrated_apps)
Par conséquent, executor.loader.unmigrated_apps
Contiendra le libellé de unmigrated_app, et si vous avez une clé étrangère vers auth_user de Django, cela provoquera une contrainte d'erreur de clé étrangère à l'époque, il n'y a pas de table nommée auth_user.
solution:
supposons que app
est le module qui contient ces classes d'attributs Foreignkey:
$ python manage.py migrate auth
$ python manage.py migrate
$ python manage.py makemigrations app
et, si d'autres modules dépendent du app
, supposons que les tables de base de données ont le même champ avec le module app
, vous avez besoin:
$ python manage.py make migrate app --fake
j'ai eu le même problème avec la clé étrangère 'author_id'.
La solution était de changer le nom de
author = models.ForeignKey(User, related_name='+')
à
writer = models.ForeignKey(User, related_name='+')
essayez donc de changer votre nom de champ pour quelque chose de différent de
group
J'ai eu la même erreur en essayant de configurer CI dans BitBucket/Pipelines. Le problème était que je n'avais pas validé le dossier des migrations dans notre référentiel git, car Pipelines reconstruit tout à partir de zéro à chaque fois, les tests unitaires ne pouvaient pas démarrer.
Le dossier des migrations est créé lorsque vous exécutez:
python manage.py makemigrations
python manage.py makemigrations <module_name>
Mes tests fonctionneraient après avoir exécuté les étapes makemigrations/migrate et vérifié que notre code non-test fonctionnait.
Il paraît que:
python manage.py test
va essayer de générer les migrations, si elles n'existent pas actuellement, mais il ne peut pas toujours obtenir les bonnes dépendances, vous devez donc vous assurer que vous validez le code généré automatiquement dans le dossier migrations dans votre référentiel de code source.
Plus de détails sur Django peuvent être trouvées ici: https://docs.djangoproject.com/en/1.11/topics/migrations/
Assurez-vous que la clé étrangère et la clé primaire sont du même type.
La clé étrangère doit être du même type que la clé primaire de la table étrangère. J'avais un bigint dans la table étrangère et Django ne savait pas comment créer automatiquement une clé étrangère qui était un bigint.
A recherché les raisons de l'échec de la migration en exécutant: python manage.py sqlmigrate {app_name} {migration_name}
Exécutez cela dans le plan de travail et vous verrez la véritable erreur derrière l'échec.
Django.db.utils.IntegrityError: (1215, 'Impossible d'ajouter une contrainte de clé étrangère')