Wie kann ich die letzte Migration rückgängig machen?

Lesezeit: 7 Minuten

Benutzeravatar von Ronen Ness
Ronen Ness

Ich habe eine Migration durchgeführt, bei der eine neue Tabelle hinzugefügt wurde, und möchte sie zurücksetzen und die Migration löschen, ohne eine neue Migration zu erstellen.

Wie mache ich es? Gibt es einen Befehl, um die letzte Migration rückgängig zu machen und dann kann ich die Migrationsdatei einfach löschen?

Benutzeravatar von Alasdair
Alasdair

Sie können durch zurückkehren Migration auf die vorherige Migration.

Beispiel: Ihre letzten beiden Migrationen sind:

  • 0010_previous_migration
  • 0011_migration_to_revert

Dann würden Sie tun:

./manage.py migrate my_app 0010_previous_migration 

Sie müssen eigentlich nicht den vollständigen Migrationsnamen verwenden, die Nummer reicht aus, dh

./manage.py migrate my_app 0010 

Anschließend können Sie die Migration löschen 0011_migration_to_revert.

Wenn Sie Django 1.8+ verwenden, können Sie die Namen aller Migrationen mit anzeigen

./manage.py showmigrations my_app

Um alle Migrationen für eine App rückgängig zu machen, können Sie Folgendes ausführen:

./manage.py migrate my_app zero

  • Ich habe auf SO viele Antworten auf dieses Problem gesehen, die alt sind und einfach nicht mehr funktionieren. +1, weil dies mit Django 1.8 funktioniert.

    – AlanSE

    7. März 2016 um 14:11 Uhr

  • Möchten Benutzer nicht normalerweise auch die Migrationsdatei löschen? Ich erwische mich oft dabei, dass ich eine Migration durchführe, sie dann überdenke und neu erstelle, bevor ich etwas Sauberes festlege, also muss ich mich normalerweise an „rm path/to/0011_migration_to_revert.py“ erinnern.

    – LisaD

    14. September 2016 um 23:54 Uhr

  • @Ness das “demigriert” nur. Wenn Sie diese Migration nicht mehr durchführen möchten, müssen Sie auch die Migrationsdatei löschen.

    – Diätspeck

    21. März 2017 um 14:47 Uhr

  • Solange Sie Ihren tatsächlichen Migrationsnamen verwenden und nicht '0010_previous_migration'ich weiß nicht, warum Sie dieses Verhalten sehen würden.

    – Alasdair

    3. Juli 2017 um 19:02 Uhr

  • Mit Django 2.1 funktioniert das für mich: /manage.py migrate my_app 0010nur 0010, nicht der vollständige Dateiname. Löschen Sie danach manuell die lokalen Dateien appname/migrations/0011+ und löschen Sie dann manuell Zeile(n) aus der Datenbanktabelle django_migrations für 0011+.

    – Emily

    17. März 2019 um 3:36 Uhr

Benutzeravatar von AlanSE
AlanSE

Die Antwort von Alasdair deckt die Grundlagen ab

  • Identifizieren Sie die gewünschten Migrationen ./manage.py showmigrations
  • migrate Verwenden Sie den App-Namen und den Migrationsnamen

Aber es sollte darauf hingewiesen werden, dass nicht alle Migrationen kann umgekehrt werden. Dies passiert, wenn Django keine Regel für die Umkehrung hat. Für die meisten Änderungen, die Sie automatisch durch Migrationen vorgenommen haben ./manage.py makemigrations, die Umkehrung ist möglich. Bei benutzerdefinierten Skripten muss jedoch sowohl vorwärts als auch rückwärts geschrieben werden, wie im Beispiel hier beschrieben:

https://docs.djangoproject.com/en/1.9/ref/migration-operations/

Wie man eine No-Op-Umkehrung durchführt

Wenn du eine hättest RunPython Vorgang, dann möchten Sie vielleicht einfach die Migration rückgängig machen, ohne ein logisch rigoroses Umkehrskript zu schreiben. Der folgende schnelle Hack zum Beispiel aus der Dokumentation (Link oben) ermöglicht dies und belässt die Datenbank in demselben Zustand, in dem sie sich nach der Anwendung der Migration befand, auch nachdem sie rückgängig gemacht wurde.

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

def forwards_func(apps, schema_editor):
    # We get the model from the versioned app registry;
    # if we directly import it, it'll be the wrong version
    Country = apps.get_model("myapp", "Country")
    db_alias = schema_editor.connection.alias
    Country.objects.using(db_alias).bulk_create([
        Country(name="USA", code="us"),
        Country(name="France", code="fr"),
    ])

class Migration(migrations.Migration):

    dependencies = []

    operations = [
        migrations.RunPython(forwards_func, lambda apps, schema_editor: None),
    ]

Dies funktioniert für Django 1.8, 1.9


Update: Eine bessere Schreibweise wäre zu ersetzen lambda apps, schema_editor: None mit migrations.RunPython.noop im Ausschnitt oben. Diese beiden sind funktional dasselbe. (Dank an die Kommentare)

  • Ab Django 1.8 sollten Sie verwenden RunPython.noop anstelle eines Inline-Lambdas oder Äquivalents: docs.djangoproject.com/en/1.8/ref/migration-operations/…

    – SpoonMeiser

    10. Oktober 2016 um 14:01 Uhr


  • @SpoonMeiser In der Syntax des Beispiels sieht das glaube ich so aus migrations.RunPython(forwards_func, migrations.RunPython.noop). Müsste das auf Funktion prüfen. Das sollte irgendwann als Antwort oder Bearbeitung hinzugefügt werden.

    – AlanSE

    10. Oktober 2016 um 17:48 Uhr

Benutzeravatar von DanGoodrick
DanGoodrick

Löschen Sie die Migrationsdatei erst nach der Umkehrung. Ich habe diesen Fehler gemacht und ohne die Migrationsdatei wusste die Datenbank nicht, welche Dinge entfernt werden sollten.

python manage.py showmigrations
python manage.py migrate {app name from show migrations} {00##_migration file.py}

Wenn Sie alle Migrationen rückgängig machen möchtenverwenden zero als Name der Migration:

python manage.py migrate app_name_here zero

Löschen Sie die Migrationsdatei. Sobald die gewünschte Migration in Ihren Modellen ist …

python manage.py makemigrations
python manage.py migrate

Hier ist meine Lösung, da die obige Lösung den Anwendungsfall nicht wirklich abdeckt, wenn Sie verwenden RunPython.

Sie können über das ORM mit auf die Tabelle zugreifen

from django.db.migrations.recorder import MigrationRecorder

>>> MigrationRecorder.Migration.objects.all()
>>> MigrationRecorder.Migration.objects.latest('id')
Out[5]: <Migration: Migration 0050_auto_20170603_1814 for model>
>>> MigrationRecorder.Migration.objects.latest('id').delete()
Out[4]: (1, {u'migrations.Migration': 1})

So können Sie die Tabellen abfragen und die für Sie relevanten Einträge löschen. Auf diese Weise können Sie im Detail modifizieren. Mit RynPython Bei Migrationen müssen Sie sich auch um die Daten kümmern, die hinzugefügt/geändert/entfernt wurden. Das obige Beispiel zeigt nur, wie Sie über Djang ORM auf die Tabelle zugreifen.

Ich habe dies in 1.9.1 getan (um die letzte oder letzte erstellte Migration zu löschen):

  1. rm <appname>/migrations/<migration #>*

    Beispiel: rm myapp/migrations/0011*

  2. in die Datenbank eingeloggt und dieses SQL ausgeführt (postgres in diesem Beispiel)

    delete from django_migrations where name like '0011%';

Ich konnte dann neue Migrationen erstellen, die mit der Migrationsnummer begannen, die ich gerade gelöscht hatte (in diesem Fall 11).

  • +1 Obwohl dies funktionieren wird, müssen Sie auf diese Weise als letzten Ausweg speichern. Außerdem müssen Sie daran denken, Spalten/Tabellen zu bearbeiten/zu löschen, zu denen die problematische Migration beigetragen hat.

    – nehem

    23. Februar 2017 um 2:05 Uhr

  • guter Punkt – ich habe dies verwendet, als ich eine Migration erstellt habe, aber “./manage.pymigration ” noch nicht ausgeführt habe

    – Mikee

    23. Februar 2017 um 17:41 Uhr

Benutzeravatar von Radwan Abu-Odeh
Radwan Abu-Odeh

So machen Sie eine Migration rückgängig:

python manage.py migrate <APP_NAME> <MIGRATION_NUMBER_PREFIX>

MIGRATION_NUMBER_PREFIX ist beispielsweise das Nummernpräfix der Migration, zu der Sie zurückkehren möchten 0001 zu gehen 0001_initial.py Migration. dann können Sie diese Migration löschen.

Sie können verwenden zero als Ihre Migrationsnummer, um alle Migrationen einer App rückgängig zu machen.

  • +1 Obwohl dies funktionieren wird, müssen Sie auf diese Weise als letzten Ausweg speichern. Außerdem müssen Sie daran denken, Spalten/Tabellen zu bearbeiten/zu löschen, zu denen die problematische Migration beigetragen hat.

    – nehem

    23. Februar 2017 um 2:05 Uhr

  • guter Punkt – ich habe dies verwendet, als ich eine Migration erstellt habe, aber “./manage.pymigration ” noch nicht ausgeführt habe

    – Mikee

    23. Februar 2017 um 17:41 Uhr

Die andere Sache, die Sie tun können, ist, die manuell erstellte Tabelle zu löschen.

Außerdem müssen Sie diese bestimmte Migrationsdatei löschen. Außerdem müssen Sie Löschen Sie diesen bestimmten Eintrag in der Tabelle django-migrations(wahrscheinlich der letzte in Ihrem Fall), der mit dieser bestimmten Migration korreliert.

  • Seien Sie in diesem Fall vorsichtig – Sie müssen überprüfen, ob db angemessen ist.

    – Sławomir Lenart

    10. Mai 2016 um 15:25 Uhr

  • Ich würde SEHR vorsichtig hinzufügen. Sie könnten viele Dinge in Postgres brechen, zum Beispiel Einschränkungen.

    – joedborg

    24. Mai 2016 um 14:24 Uhr

  • Dies funktioniert, wenn die Tabelle keine Fremdschlüssel hat, es wird nicht empfohlen

    – Touhami

    18. November um 9:21 Uhr


1436570cookie-checkWie kann ich die letzte Migration rückgängig machen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy