Ich habe ein Django 1.8-Projekt gestartet, das das Migrationssystem verwendet.
Irgendwie wurde es auf dem Weg chaotisch, also habe ich die Migrationsordner und -tabellen aus der Datenbank gelöscht und jetzt versuche ich, sie ohne Erfolg zu rekonstruieren.
Ich habe drei Apps (3 models.py
Dateien) und die Modelle spiegeln die Tabellen genau wider!
Der beste Ansatz, den ich bisher gefunden habe, war:
- Löschen Sie alle
migrations
Ordner. Erledigt! - Löschen Sie alles aus der
django_migrations
Tabelle. Erledigt! - Führen Sie
python manage.py makemigrations --empty <app>
für jede App. Erledigt! - Ausführen
python manage.py migrate --fake
. Erledigt! (obwohl es nur funktioniert, wenn ich es nach jedemmakemigrations
Befehl ausführe .
Jetzt füge ich ein neues Feld hinzu, führe den makemigrations
Befehl aus und erhalte die folgende Fehlermeldung:
django.db.utils.OperationalError: (1054, "Unknown column 'accounts_plan.max_item_size' in 'field list'")
Ich habe STUNDEN auf dieses Ding gebrannt. Wie kann ich die Migrationen initialisieren, damit ich jedes Mal ohne Migrationsunterbrechungen weiterarbeiten kann?
Warum ist es so kompliziert? Warum gibt es keinen einfachen Einzeiler initiate_migrations_from_schema
?
EDIT:
Jetzt wird es noch schlimmer. Ich habe die django_migrations
Tabelle abgeschnitten und den gesamten migrations
Ordner gelöscht .
Jetzt versuche ich auszuführen python manage.py migrate --fake-initial
(etwas, das ich in den DEV-Dokumenten gefunden habe), nur damit alle 'internen' Apps von Django (Authentifizierung, Sitzung usw.) eingerichtet werden und ich bekomme :
(1054, "Unknown column 'name' in 'django_content_type'")
.
Diese "Spalte" ist keine echte Spalte. Es ist eine @property
in Djangos contenttypes
App definierte. WAS GEHT HIER VOR SICH? Warum wird die name
Eigenschaft als echte Spalte identifiziert ?
quelle
delete from django_migrations
Antworten:
Endlich hat es funktioniert, obwohl ich nicht weiß warum und ich hoffe, dass es in Zukunft funktionieren wird.
Nach zahlreichen Versuchen und Durchlaufen der Entwicklungsseite von Django ( Link ).
Hier sind die Schritte (für alle, die auf dieses Problem stoßen):
django_migrations
Tisch:delete from django_migrations;
migrations
Ordner:rm -rf <app>/migrations/
python manage.py migrate --fake
python manage.py makemigrations <app>
. Achten Sie auf Abhängigkeiten (Modelle mit ForeignKey sollten nach dem übergeordneten Modell ausgeführt werden).python manage.py migrate --fake-initial
Danach habe ich den letzten Befehl ohne
--fake-initial
Flag ausgeführt, nur um sicherzugehen.Jetzt funktioniert alles und ich kann das Migrationssystem normal verwenden.
Ich bin sicher, dass ich nicht der einzige bin, der auf dieses Problem stößt. Es muss besser dokumentiert und sogar vereinfacht werden.
Update für Django 1.9-Benutzer:
Ich hatte dieses Szenario erneut mit einem Django 1.9.4 und Schritt 5 schlug fehl.
Alles , was ich hatte , ist zu ersetzen zu tun
--fake-initial
mit--fake
ihm arbeiten zu lassen.quelle
RuntimeError: Error creating new content types. Please make sure contenttypes is migrated before trying to migrate apps individually.
zum letzten Schritt für Django 1.8.3. Weißt du, warum?python manage.py migrate contenttypes
vor dem letzten Schritt zu laufen .django ..., 1,8, 1,9, ...
Was Sie erreichen möchten, ist, vorhandene Migrationen zu unterdrücken und diese zu ersetzen.
So machen Sie es richtig, ohne beim Freigeben einen Befehl zu verwenden (ein Fall ohne Auswirkungen auf Datenbank und Mitarbeiter).
Entfernen Sie für jede App den Migrationsordner:
mv <app>/migrations/ <app>/migrationsOLD/
Für jeden App-Lauf :
python manage.py makemigrations <app>
.Passen Sie jede neue Migration an:
Wenn Sie eine komplexe App oder mehrere Apps und verwandte Modelle zwischen sich haben, um Folgendes zu vermeiden
CircularDependencyError
oderValueError: Unhandled pending operations for models
:Bereiten Sie die zweite leere Migration in vor
<app>
0002_initial2.py
(setzen Sie dort die Abhängigkeit zuapp_other::0001_initial.py
und<app>
::0001_initial.py
- alle ForeignKey, M2M, die sich auf Modelle beziehen, die im Migrationsschritt 0001 in anderen Apps erstellt wurden).Alles muss in Ordnung sein - manchmal sind mehr Migrationen erforderlich, um sich vorzubereiten. Achten Sie
dependencies
hier bei jeder Migration auf die Attribute.Achten Sie auf die Anfangswerte - überprüfen Sie alle
RunPython
Aktionen vonmigrationsOLD
und kopieren Sie den Code bei Bedarf in die neue Erstmigration.(optional für
--fake-initial
)initial=True
Zu allen neuen Migrationsklassen hinzufügen (auch 0002, falls hinzugefügt).replaces
Attribute in neuer Migration Klasse. (wie eigene Gewohnheit asquashmigrations
). Legen Sie dort alle alten Migrationen von<app>
Überprüfen Sie alles mit
makemigrations
.behaupten "Keine Änderungen erkannt"
Überprüfen Sie, ob
migrate -l
überall [x] angezeigt wirdbehaupten ähnlich:
[X] 0001_initial
[X] 0002_initial2 (102 gequetschte Migrationen)
Beispiel:
Für alte:
0001_initial.py 0002_auto.py ... 0103_auto.py
bereiten:
0001_initial.py 0002_initial2.py (optional but sometimes required to satisfy dependency)
und
replaces
zum letzten hinzufügen (0002 hier, kann 0001 sein):replaces = [(b'<app>', '0002_auto.py'), ..., (b'<app>', '0103_auto.py')]
0001_initial.py sollte genauso benannt werden wie die alte.
0002_initial2.py ist neu, ersetzt jedoch alte Migrationen, sodass Django sie als geladen behandelt.
quelle
Ich bin auf dieses Szenario gestoßen, musste aber nie die Datenbank löschen, um es zu lösen. Normalerweise lösche ich den Migrationsordner aus der App und entferne die Migrationseinträge aus der Datenbank.
Ich würde versuchen, Migrationen einzeln durchzuführen. Wenn sich eine der Apps auf andere Tabellen stützt, fügen Sie diese offensichtlich zuletzt hinzu.
Außerdem starte ich normalerweise nur python manage.py makemigrations und dann nur python manage.py migrate. Selbst bei der anfänglichen Migration sollte es mit Django 1.7 und 1.8 gut funktionieren.
quelle
migrate
Befehl versucht, die Tabellen (die bereits vorhanden sind) zu erstellen ...manage.py makemigrations: error: unrecognized arguments: --initial
Wenn Sie Router verwenden, liegt dort möglicherweise ein Problem vor. Überprüfen Sie die Methode,
allow_migrate
ob sie ordnungsgemäß ausgeführt wurderouters.py
. Versuchen Sie, den Rückgabewert immer so einzustellen, dassTrue
er das Problem behebt.def allow_migrate(self, db, app_label, model_name=None, **hints): return True
quelle