Django 1.7 - Makemigrations ne détecte pas les changements

140

Comme le titre l'indique, je n'arrive pas à faire fonctionner les migrations.

L'application était à l'origine sous 1.6, donc je comprends que les migrations ne seront pas là au départ, et en effet si je l'exécute, python manage.py migratej'obtiens:

Operations to perform:
  Synchronize unmigrated apps: myapp
  Apply all migrations: admin, contenttypes, auth, sessions
Synchronizing apps without migrations:
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Running migrations:
  No migrations to apply.

Si je modifie un modèle dans myapp, il est toujours indiqué non migré, comme prévu.

Mais si je cours, python manage.py makemigrations myappj'obtiens:

No changes detected in app 'myapp'

Cela ne semble pas avoir d'importance ou comment j'exécute la commande, cela ne détecte jamais l'application comme ayant des modifications, ni n'ajoute de fichiers de migration à l'application.

Existe-t-il un moyen de forcer une application à migrer et de dire essentiellement "C'est ma base pour travailler" ou quoi que ce soit? Ou est-ce que je manque quelque chose?

Ma base de données est une base de données PostgreSQL si cela aide du tout.

TyrantWave
la source
Les solutions proposées ne fonctionnaient pas pour moi, alors voici ma solution si quelqu'un est confronté au même problème! 1. Supprimez les fichiers de migration sous toutes les applications 2. Supprimez la base de données et créez-la à nouveau 3. exécutez makemigrations et migrez les commandes PS Essayez d'abord les étapes 1 et 3. S'il y a toujours une erreur, suivez les étapes 1 à 3.
Amoroso

Réponses:

187

Si vous passez d'une application existante que vous avez créée dans django 1.6, vous devez effectuer une étape préalable (comme je l'ai découvert) répertoriée dans la documentation:

python manage.py makemigrations your_app_label

La documentation ne rend pas évident que vous devez ajouter l'étiquette d'application à la commande, car la première chose qu'elle vous dit de faire est de savoir python manage.py makemigrationslaquelle échouera. La migration initiale est effectuée lorsque vous créez votre application dans la version 1.7, mais si vous étiez originaire de la version 1.6, elle n'aurait pas été effectuée. Consultez la rubrique «Ajout de la migration aux applications» dans la documentation pour plus de détails.

drojf
la source
1
Bonne réponse pour les personnes venant de Django 1.6! Merci!
David D.
1
Et si j'ai bien plus d'une application? Dois-je le faire python manage.py makemigrations APP_LABELpour chacun?
Alston
1
Sous Django 1.9 ici et mon application a été créée avec ./manage.py startapp, mais je devais quand même mentionner explicitement le label
maxbellec
50

Cela peut se produire pour les raisons suivantes:

  1. Vous n'avez pas ajouté l'application dans la INSTALLED_APPSliste dans settings.py (vous devez ajouter le nom de l' application ou le chemin en pointillé à la sous-classe d'AppConfig dans apps.py dans le dossier de l'application, en fonction de la version de django que vous utilisez). Reportez-vous à la documentation: INSTALLED_APPS
  2. Vous n'avez pas de migrationsdossier dans ces applications. (Solution: créez simplement ce dossier).
  3. Vous n'avez pas de __init__.pyfichier dans le migrationsdossier de ces applications. (Solution: créez simplement un fichier vide avec le nom __init__.py )
  4. Vous n'avez pas de __init__.pyfichier dans le dossier de l'application. (Solution: créez simplement un fichier vide avec le nom __init__.py )
  5. Vous n'avez pas de models.pyfichier dans l'application
  6. Votre classe Python (censée être un modèle) dans models.pyn'hérite pasdjango.db.models.Model
  7. Vous avez une erreur sémantique dans la définition des modèles dans models.py

Remarque: une erreur courante consiste à ajouter un migrationsdossier dans un .gitignorefichier. Lorsqu'il est cloné à partir du référentiel distant, le migrationsdossier et / ou les __init__.pyfichiers seront manquants dans le référentiel local. Cela pose problème.

Je suggère de gitignore les fichiers de migration en ajoutant les lignes suivantes au .gitignorefichier

*/migrations/*
!*/migrations/__init__.py
Mohammed Shareef C
la source
1
J'avais cloné mon projet et le dossier migrations n'était pas poussé vers le référentiel donc j'ai dû ajouter le directeur des migrations puis j'ai ajouté le init .py et j'ai pu faire des migrations. Merci à vous
Junaid
J'ai supprimé le contenu de mon dossier / migrations pour "réinitialiser" des éléments sur un projet que je n'avais pas encore déployé. J'ai supprimé par inadvertance le __init__.pydossier avec les migrations.
Seth
Cela l'a fait pour moi .... You don't have __init__.py file inside migrations folder of those apps. (Solution: Just create an empty file with name __init__.py).. et cela a été causé par l'ajout des fichiers à.gitignore
lukik
1
Pourquoi le fichier init .py est-il si important dans le dossier des migrations? faire des migrations? Où puis-je creuser plus profondément pour cette logique?
Nimish Bansal
1
@NimishBansal Jusqu'à ce que le __init__.pyfichier python 3.3 soit requis dans un répertoire pour qu'il soit traité comme un package python. voir ça
Mohammed Shareef C
29

Ok, on dirait que j'ai raté une étape évidente, mais poster ceci au cas où quelqu'un d'autre ferait de même.

Lors de la mise à niveau vers la version 1.7, mes modèles sont devenus non gérés ( managed = False) - je les avais comme Trueavant, mais il semble qu'ils ont été rétablis.

La suppression de cette ligne (par défaut sur True), puis l'exécution makemigrationsimmédiate d'un module de migration et maintenant cela fonctionne. makemigrationsne fonctionnera pas sur les tables non gérées (ce qui est évident avec le recul)

TyrantWave
la source
4
Veuillez clarifier - où avez-vous changé / ajouté "managed = False"? J'ai le même problème
Ycon
1
Je n'ai plus ce code, mais je pense comme une propriété de la classe si je me souviens bien.
TyrantWave
1
Bon point. Notez que manage.py inspectdbajoute manage = False! au cas où vous importeriez des bases de données héritées, vous devez les régler soigneusement!
Alessandro Dentella
@TyrantWave, tu as sauvé ma journée. Merci beaucoup.
Utkarsh Sharma
assurez-vous que votre app_labelest le même
Luv33preet
19

Ma solution n'a pas été traitée ici, je la poste donc. J'avais utilisé syncdbpour un projet - juste pour le faire fonctionner. Ensuite, quand j'ai essayé de commencer à utiliser les migrations Django, cela les a d'abord simulées, puis j'ai dit que c'était `` OK '' mais rien ne se passait pour la base de données.

Ma solution consistait simplement à supprimer tous les fichiers de migration de mon application, ainsi que les enregistrements de base de données pour les migrations d'applications dans le django_migrationstableau.

Ensuite, je viens de faire une migration initiale avec:

./manage.py makemigrations my_app

suivi par:

./manage.py migrate my_app

Maintenant, je peux faire des migrations sans problème.

Grant Eagon
la source
FYI: il est essentiel qu'il dise ici, "les fichiers, ainsi que les enregistrements de la base de données." Si vous supprimez les enregistrements de la base de données mais pas les fichiers également (sauf pour __init.py__, cela ne fonctionnera pas.
Mike Robinson
15

D'accord avec @furins. Si tout semble être en ordre et que ce problème survient, vérifiez s'il existe une méthode de propriété avec le même titre que l'attribut que vous essayez d'ajouter dans la classe Model.

  1. Supprimez la méthode avec un nom similaire à l'attribut que vous ajoutez.
  2. manage.py makemigrations my_app
  3. manage.py migrer my_app
  4. Ajoutez les méthodes.
Prashant Nair
la source
11

C'est une sorte d'erreur stupide à faire, mais avoir une virgule supplémentaire à la fin de la ligne de déclaration de champ dans la classe de modèle, fait que la ligne n'a aucun effet.

Cela se produit lorsque vous copiez collez le fichier def. de la migration, elle-même définie comme un tableau.

Mais peut-être que cela aiderait quelqu'un :-)

Iman Akbari
la source
1
Votre commentaire m'a aidé à trouver mon problème! Je n'avais pas de virgule à la fin du dernier choix dans une liste de choix. Apparemment, Django est très délicat.
Maxim
1
@Maxim: c'était peu probable la cause de votre problème: une liste sans virgule à la fin est toujours une liste. Un autre problème concerne les tuples: si vous n'avez qu'un seul élément dans un tuple, vous avez besoin d'une virgule après.
blueFast le
mec qui m'a sauvé beaucoup de temps! @dangonfast: dans la définition du modèle, c'est effectivement un problème.
MrE
11

Peut-être que je suis trop tard, mais avez-vous essayé d'avoir un migrationsdossier dans votre application avec un __init__.pyfichier?

rrrub
la source
1
Si vous avez ce "makemigrations" va créer les migrations pour l'application. Sinon, il vous faudra exécuter makemigrations app_name (qui crée ces fichiers)
Scott Warren
7

Peut-être que cela aidera quelqu'un. J'utilisais une application imbriquée. project.appname et j'avais en fait project et project.appname dans INSTALLED_APPS. La suppression du projet de INSTALLED_APPS a permis de détecter les modifications.

jaywhy13
la source
7

La réponse est sur ce post stackoverflow, par cdvv7788 Migrations dans Django 1.7

Si c'est la première fois que vous migrez cette application, vous devez utiliser:

manage.py makemigrations myappname Une fois que vous faites cela, vous pouvez faire:

manage.py migrate Si vous aviez votre application dans la base de données, modifiiez son modèle et ne mettiez pas à jour les modifications sur makemigrations, vous ne l'avez probablement pas encore migrée. Remettez votre modèle dans sa forme d'origine, exécutez la première commande (avec le nom de l'application) et migrez ... il le simulera. Une fois que vous avez fait cela, réinstallez les modifications sur votre modèle, exécutez makemigrations et migrez à nouveau et cela devrait fonctionner.

J'avais exactement le même problème et faire ce qui précède fonctionnait parfaitement.

J'avais déplacé mon application django vers cloud9 et pour une raison quelconque, je n'ai jamais attrapé la migration initiale.

MicahT
la source
7

La suite a fonctionné pour moi:

  1. Ajoutez le nom de l'application à settings.py
  2. utilisez 'python manage.py makemigrations'
  3. utiliser 'python manage.py migrate'

A travaillé pour moi: Python 3.4, Django 1.10

Pranshu Gupta
la source
6

Les gens comme moi qui n'aiment pas les migrations peuvent utiliser les étapes ci-dessous.

  1. Supprimez les modifications que vous souhaitez synchroniser.
  2. Exécutez python manage.py makemigrations app_labelpour la migration initiale.
  3. Exécutez python manage.py migratepour créer des tables avant d'apporter des modifications.
  4. Collez les modifications que vous supprimez à la première étape.
  5. Exécutez les étapes 2. et 3..

Si vous avez confondu l'une de ces étapes, lisez les fichiers de migration. Modifiez-les pour corriger votre schéma ou supprimer les fichiers indésirables, mais n'oubliez pas de modifier la partie dépendances du prochain fichier de migration;)

J'espère que cela aidera quelqu'un à l'avenir.

Deniz Kaplan
la source
5

Vous voulez vérifier settings.pydans la INSTALLED_APPSliste et vous assurer que toutes les applications avec des modèles y sont répertoriées.

L'exécution makemigrationsdans le dossier du projet signifie qu'il cherchera à mettre à jour toutes les tables liées à toutes les applications incluses dans settings.pyle projet. Une fois que vous l'avez inclus, makemigrationsl'application inclura automatiquement (cela économise beaucoup de travail afin que vous n'ayez pas à exécuter makemigrations app_namepour chaque application de votre projet / site).

Gluant
la source
5

Juste au cas où vous auriez un champ spécifique qui ne serait pas identifié par makemigrations: vérifiez deux fois si vous avez une propriété avec le même nom.

exemple:

field = django.db.models.CharField(max_length=10, default = '', blank=True, null=True)

# ... later

@property
def field(self):
    pass

la propriété "écrasera" la définition du champ afin que les modifications ne soient pas identifiées par makemigrations

furines
la source
Un problème lié est d'avoir un champ mal formé qui échappe toujours à la validation / vérification. J'ai défini hourly_rate = models.DecimalField(il manque le '()' à la fin) et cela a échoué en silence.
sage
5

Assurez-vous que votre modèle ne l'est pas abstract. J'ai fait cette erreur et cela a pris un certain temps, alors j'ai pensé que je la publierais.

marque
la source
4

Ajout de cette réponse car seule cette méthode m'a aidé.

J'ai supprimé le migrationsdossier run makemigrationset migrate.
Il a toujours dit: aucune migration à appliquer.

Je suis allé dans le migratedossier et j'ai ouvert le dernier fichier créé,
commenté la migration que je voulais (elle a été détectée et entrée là-bas)
et je suis à migratenouveau exécutée .

Ceci édite essentiellement le fichier de migrations manuellement.
Ne le faites que si vous comprenez le contenu du fichier.

Jithin Pavithran
la source
1
Merci beaucoup! Cela a aidé
Sharpless512
3

Avez-vous utilisé schemamigration my_app --initialaprès avoir renommé l'ancien dossier de migration? Essayez-le. Pourrait fonctionner. Sinon, essayez de recréer la base de données et faites migrer syncdb +. Cela a fonctionné pour moi ...

Alex Vidis
la source
10
Aucune commande schemamigrationn'existe - je pense que cela fait partie du sud? Je n'ai pas du tout de dossier de migration actuellement. La suppression de mon models.pyet la réexécution inspectdbne semblaient rien faire.
TyrantWave
2
schemamigrationvenait du sud. makemigrationsest son remplacement.
Craig Labenz
2
Ceci est toujours valable. Mais il a changé pourmakemigrations --empty
Iulius Curt
2

J'ai eu le même problème Assurez-vous que quelles que soient les classes que vous avez définies dans models.py, vous devez hériter de la classe models.Model.

class Product(models.Model):
    title = models.TextField()
    description = models.TextField()
    price = models.TextField()
Sonu Kumar
la source
1

J'ai eu le même problème de devoir exécuter makemigrations deux fois et toutes sortes de comportements étranges. Il s'est avéré que la racine du problème était que j'utilisais une fonction pour définir les dates par défaut dans mes modèles, de sorte que les migrations détectaient un changement chaque fois que j'exécutais makemigrations. La réponse à cette question m'a mis sur la bonne voie: évitez de faire des migrations pour recréer le champ de date

PhoebeB
la source
1

J'ai récemment mis à niveau Django de la 1.6 à la 1.8 et ai eu peu d'applications et de migrations pour eux. J'ai utilisé south et schemamigrationspour créer des migrations dans Django 1.6, qui est abandonné dans Django 1.8.

Lorsque j'ai ajouté de nouveaux modèles après la mise à niveau, la makemigrationscommande ne détectait aucun changement. Et puis j'ai essayé la solution suggérée par @drojf (1ère réponse), cela a bien fonctionné, mais n'a pas réussi à appliquer une fausse migration initiale ( python manage.py --fake-initial). Je faisais cela car mes tables (anciennes tables) étaient déjà créées.

Enfin, cela a fonctionné pour moi, j'ai supprimé les nouveaux modèles (ou les modifications de modèle) de models.py, puis j'ai dû supprimer (ou renommer pour la sauvegarde de sécurité) le dossier de migrations de toutes les applications et exécuter python manage.pymakemigrations pour toutes les applications, puis l'a fait python manage.py migrate --fake-initial. Cela a fonctionné comme un charme. Une fois la migration initiale créée pour toutes les applications et la fausse migration initiale, puis ajouté de nouveaux modèles et suivi du processusmakemigrations migration sur cette application. Les changements ont été détectés maintenant et tout s'est bien passé.

J'ai juste pensé à le partager ici, si quelqu'un fait face au même problème (avoir schemamigrationsdu sud pour ses applications), cela pourrait les aider :)

RaghavHarpale
la source
1

Peut-être que cela peut aider quelqu'un, j'ai eu le même problème.

J'ai déjà créé deux tables avec la classe de sérialiseur et les vues. Donc, quand j'ai voulu mettre à jour, j'ai eu cette erreur.

J'ai suivi ces étapes:

  1. J'ai fait .\manage.py makemigrations app
  2. J'ai exécuté .\manage.py migrate
  3. J'ai effacé les deux tableaux de mon models.py
  4. J'ai effacé toute référence à mes tables du sérialiseur et de la classe de vue.
  5. J'ai exécuté l'étape 1et 2.
  6. J'ai récupéré mes modifications juste dans le models.py
  7. J'ai exécuté à nouveau l'étape 5.
  8. J'ai restauré toutes mes modifications.

Si vous travaillez avec Pycharm, l'histoire locale est très utile.

empreintes
la source
1

Peut-être que cela aidera quelqu'un.

J'ai supprimé mon models.pyet je m'attendais makemigrationsà créer des DeleteModeldéclarations.

N'oubliez pas de supprimer les *.pycfichiers!

Sébastien Wagner
la source
1
./manage makemigrations
./manage migrate

Les migrations suivent les modifications apportées à la base de données, donc si vous passez de non géré à géré, vous devrez vous assurer que votre table de base de données est à jour par rapport au modèle avec lequel vous traitez.

Si vous êtes toujours en mode dev, j'ai personnellement décidé de supprimer les fichiers de migration dans mon IDE ainsi que dans la table django_migrations relative à mon modèle et de réexécuter la commande ci-dessus.

RAPPELEZ-VOUS: si vous avez une migration qui se termine par _001 dans votre IDE et _003 dans votre base de données. Django ne verra que si vous avez une migration se terminant par _004 pour quoi que ce soit à mettre à jour.

Les 2 (migrations de code et de base de données) sont liés et fonctionnent en tandem.

Bon codage.

AH Bensiali
la source
1
  1. Supprimez les modifications que vous souhaitez synchroniser.
  2. Exécutez python manage.py makemigrations app_label pour la migration initiale.
  3. Exécutez python manage.py migrate pour créer des tables avant d'apporter des modifications.
  4. Collez les modifications que vous supprimez à la première étape.
  5. Exécutez les étapes 2. et 3.
Vijay Choudhary
la source
0

Ajout de cette réponse car aucun des autres disponibles ci-dessus n'a fonctionné pour moi.

Dans mon cas, quelque chose d'encore plus étrange se passait ( version Django 1.7 ), dans mon models.py j'avais une ligne "extra" à la fin de mon fichier (c'était une ligne vide) et quand j'ai exécuté la python manage.py makemigrationscommande, le résultat était: "aucun changement détecté".

Pour résoudre ce problème, j'ai supprimé cette "ligne vide" qui se trouvait à la fin de mon fichier models.py et j'ai relancé la commande, tout a été corrigé et toutes les modifications apportées à models.py ont été détectées!

Huskie
la source
Eh bien dans django 2.0 + cette ligne vide est nécessaire, je crois, je devais faire le contraire de ce que vous avez fait mon pote
Sumit Kumar Saha
@SumitKumarSaha haha ​​J'utilise actuellement la version Django 1.7 et cette ligne vide était la raison pour laquelle 2 heures ont tout essayé pour résoudre l'erreur de migration. Merci d'avoir partagé Sumit. Bonne journée
Huskie
0

Vous devrez peut-être simuler les migrations initiales à l'aide de la commande ci-dessous

python manage.py migrate --fake-initial
dtar
la source
0

Tout d'abord, cette solution est applicable à ceux qui sont confrontés au même problème lors du déploiement sur le serveur heroku, j'étais confronté au même problème.

Pour déployer, il y a une étape obligatoire qui consiste à ajouter django_heroku.settings (locals ()) dans le fichier settings.py.

Changements: Lorsque j'ai changé la ligne ci-dessus en django_heroku.settings (locals (), databases = False), cela fonctionnait parfaitement.

Rishabh Aher
la source
0

Dans mon cas, je devais ajouter mon modèle au fichier _ init _.py du dossier models où mon modèle a été défini:

from myapp.models.mymodel import MyModel
Robert Wallace
la source
-1

Ajout de mon 2c, car aucune de ces solutions n'a fonctionné pour moi, mais cela a fonctionné ...

Je venais de lancer manage.py squashmigrationset de supprimer les anciennes migrations (les fichiers et les lignes de la table de base de données django.migrations).

Cela a laissé une ligne comme celle-ci dans le dernier fichier de migration:

replaces = [(b'my_app', '0006_auto_20170713_1735'), (b'my_app', '0007_auto_20170713_2003'), (b'my_app', '0008_auto_20170713_2004')]

Cela a apparemment perturbé Django et provoqué un comportement étrange: l'exécution manage.py makemigrations my_apprecréerait la migration initiale comme si aucune n'existait. La suppression de la replaces...ligne a résolu le problème!

webtweakers
la source
-1

python manage.py makemigrations accounts Migrations pour 'accounts': accounts \ migrations \ 0001_initial.py - Créer un modèle Client - Créer un modèle Tag - Créer un modèle Produit - Créer un modèle Commande

Remarque: ici "comptes" est le nom de mon application

Vijay Choudhary
la source