Ich habe auf der Website von South, Google und SO nach einer Antwort darauf gesucht, konnte aber keinen einfachen Weg finden, dies zu tun.
Ich möchte ein Django-Modell mit South umbenennen. Angenommen, Sie haben Folgendes:
class Foo(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
und Sie möchten nämlich Foo in Bar konvertieren
class Bar(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Bar)
Um es einfach zu halten, versuche ich nur, den Namen von Foo
in zu ändern Bar
, aber ignoriere das foo
Mitglied FooTwo
vorerst.
Was ist der einfachste Weg, dies mit South zu tun?
- Ich könnte wahrscheinlich eine Datenmigration durchführen, aber das scheint ziemlich kompliziert zu sein.
- Schreiben Sie beispielsweise eine benutzerdefinierte Migration,
db.rename_table('city_citystate', 'geo_citystate')
aber ich bin nicht sicher, wie der Fremdschlüssel in diesem Fall behoben werden soll. - Ein einfacher Weg, den Sie kennen?
python
django
django-models
rename
django-south
vaughnkoch
quelle
quelle
Antworten:
Um Ihre erste Frage zu beantworten, ist das einfache Umbenennen von Modell / Tabelle ziemlich einfach. Führen Sie den folgenden Befehl aus:
(Update 2: Versuchen Sie
--auto
stattdessen--empty
, die folgende Warnung zu vermeiden. Vielen Dank an @KFB für den Tipp.)Wenn Sie eine ältere Version von South verwenden, benötigen Sie
startmigration
stattdessenschemamigration
.Bearbeiten Sie dann die Migrationsdatei manuell wie folgt:
Sie können dies einfacher mit der
db_table
Option Meta in Ihrer Modellklasse erreichen. Aber jedes Mal, wenn Sie dies tun, erhöhen Sie das Legacy-Gewicht Ihrer Codebasis. Wenn sich Klassennamen von Tabellennamen unterscheiden, ist Ihr Code schwieriger zu verstehen und zu pflegen. Der Klarheit halber unterstütze ich die Durchführung einfacher Refactorings wie diese voll und ganz.(Update) Ich habe dies gerade in der Produktion versucht und eine seltsame Warnung erhalten, als ich die Migration anwendete. Es sagte:
Ich antwortete "nein" und alles schien in Ordnung zu sein.
quelle
Nehmen Sie die Änderungen vor
models.py
und führen Sie sie ausWenn Sie die Migrationsdatei untersuchen, werden Sie feststellen, dass eine Tabelle gelöscht und eine neue erstellt wird
Das ist nicht ganz das, was Sie wollen. Bearbeiten Sie stattdessen die Migration so, dass sie wie folgt aussieht:
Wenn die
update
Anweisung nicht vorhanden ist, wird beimdb.send_create_signal
Aufruf ein neuerContentType
mit dem neuen Modellnamen erstellt. Es ist jedoch besser, nurupdate
das zu haben, wasContentType
Sie bereits haben, falls Datenbankobjekte darauf verweisen (z. B. über aGenericForeignKey
).Wenn Sie einige Spalten umbenannt haben, die Fremdschlüssel für das umbenannte Modell sind, vergessen Sie dies nicht
quelle
contenttypes.ContentType
Modell mithilfe des--frozen
Flags zu den eingefrorenen Modellen hinzugefügt habe./manage.py datamigration
. Zum Beispiel :./manage.py datamigration --frozen contenttypes myapp update_contenttypes
. Bearbeiten Sie dann myapp_migrations / NNNN_update_contenttypes.py mit dem oben angegebenen Code zur Aktualisierung des Inhaltstyps.Der Süden kann es nicht selbst tun - woher weiß er, dass dies das
Bar
darstellt, wasFoo
früher war? Für diese Art von Dingen würde ich eine benutzerdefinierte Migration schreiben. Sie können IhrenForeignKey
In-Code wie oben beschrieben ändern. Anschließend müssen Sie nur die entsprechenden Felder und Tabellen umbenennen, was Sie nach Belieben tun können.Müssen Sie das wirklich tun? Ich muss Modelle noch umbenennen - Modellnamen sind nur ein Implementierungsdetail - insbesondere angesichts der Verfügbarkeit der
verbose_name
Meta-Option.quelle
db_table
Option Meta verwenden, um den Namen der Datenbanktabelle beizubehalten.db_table
Fremdschlüsselnamen abgeleitet werden?Ich folgte der obigen Lösung von Leopd. Dies änderte jedoch nichts an den Modellnamen. Ich habe es manuell im Code geändert (auch in verwandten Modellen, in denen dies als FK bezeichnet wird). Und eine weitere Südwanderung gemacht, aber mit --fake Option. Dadurch werden Modell- und Tabellennamen identisch.
Gerade realisiert, könnte man zuerst mit dem Ändern der Modellnamen beginnen und dann die Migrationsdatei bearbeiten, bevor man sie anwendet. Viel sauberer.
quelle