Ich habe zwei Klassen, von denen die eine von der anderen abstammt, und ich möchte sie beide zu Geschwisterklassen machen, die von derselben Basisklasse abstammen.
Vorher:
%Vor%Nachher:
%Vor%Wenn ich eine Schemamigration erzeuge, ist dies die Ausgabe, einschließlich meiner Antworten auf die Fragen:
%Vor%Ich kann die Fragen zu den Standardwerten für B.base_ptr und A.base_ptr nicht beantworten. Jede Konstante, die ich gebe, führt dazu, dass die Migration bei der Ausführung fehlschlägt:
%Vor%Das ist das Ergebnis, wenn ich sqlite3 benutze. Bei der Verwendung von Postgres gibt es so etwas:
%Vor%Welche Werte sollte ich für base_ptr verwenden, damit diese Migration funktioniert? Danke!
Sie tun dies in getrennten Phasen.
Phase 1: Erstellen Sie Ihr "Basis" -Modell im Code. Fügen Sie in den A- und B-Modellen base_ptr
als NULL-fähige FK zu Base hinzu (der Name base_ptr
wird durch Verkleinern des Klassennamens Base
erstellt, passen Sie Ihre Namen entsprechend an). Geben Sie db_column='base_ptr'
für die neue Spalte an, damit kein _id
Suffix hinzugefügt wird. Ändern Sie noch nicht die Elternschaft: Behalten Sie B
als Kind von A
und A
wie zuvor ( Base
hat noch keine untergeordneten Klassen). Fügen Sie eine Migration hinzu, um die entsprechenden Datenbankänderungen vorzunehmen, und führen Sie sie aus.
Phase 2: Erstellen Sie eine Datenmigration, indem Sie relevante Daten kopieren. Sie sollten wahrscheinlich alle A
Daten in Base
kopieren, redundante A
Datensätze entfernen (diejenigen, die B
Instanzen dienten), und in den verbleibenden Datensätzen (von A
und B
) kopieren Sie die ID in% Code%. Beachten Sie, dass die untergeordnete Klasse base_ptr
zwei Tabellen verwendet - ihr B
-Feld stammt aus der Tabelle id
, und in ihrer eigenen Tabelle gibt es ein Feld A
, das ein FK nach a_ptr
- so ist Ihr Update-Vorgang wird effizienter, wenn Sie Werte von A
nach a_ptr
kopieren. Stellen Sie sicher, dass das Kopieren in base_ptr nach dem Kopieren in die Tabelle base_ptr
erfolgt, damit Sie die FK-Einschränkungen nicht verletzen.
Phase 3: Ändern Sie jetzt die Modelle erneut - entfernen Sie das explizite Base
FK und ändern Sie die Eltern so, wie Sie möchten, und erstellen Sie eine dritte Migration (automatische Schemamigration). Beachten Sie, dass das Festlegen des übergeordneten Elements auf base_ptr
implizit ein nicht nullbares Base
-Feld definiert. Daher ändern Sie in Bezug auf die Felder base_ptr
nur ein Nullable-Feld in ein Nicht-Nullable, und es ist kein Standardwert erforderlich.
Sie sollten immer noch nach einem Standardwert für base_ptr
gefragt werden - den impliziten FK von a_ptr
bis B
, der entfernt wird, wenn das übergeordnete Element von A
in A
geändert wird; Der Standard wird für die Migration in Rückwärtsrichtung benötigt. Sie können entweder etwas tun, das die Rückwärtsmigration nicht besteht, oder, wenn Sie es unterstützen möchten, fügen Sie eine explizite Nullwert Base
zu a_ptr
hinzu, wie die Spalten B
, die Sie zuvor verwendet haben. Diese NULL-fähige Spalte kann dann in einer vierten Migration entfernt werden.
Wenn base
bei Aktivierung nicht instanziiert wird, können Sie das Problem einfach mit abstract = True
prop bis class Meta
lösen.
Korrigierter Code:
%Vor%Tags und Links django-south