Welchen Wert verwende ich für _ptr bei der Migration von reparierten Klassen mit South?

8

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!

    
Jack Twilley 10.05.2013, 17:42
quelle

2 Antworten

3

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.

    
Shai Berger 16.02.2014, 22:26
quelle
4

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%     
Oleg Belousov 16.09.2016 20:43
quelle

Tags und Links