2010-08-14 8 views
13

eine einfache Charfield usw. Umbenennen scheinen einfach (Django - How to rename a model field using South?)Wie kann man ein Fremdschlüsselfeld mit South umbenennen?

Jedoch, wenn ich auf einem ForeignKey Feld das gleiche versuchen, mit mir eine Fehlermeldung erhalten:

_mysql_exceptions.OperationalError: (1091, "Can't DROP '[new_fkey_field_name]'; check that column/key exists") 

, die aus der Migration stammt versuchen, die rückwärts laufen aus irgendeinem Grund (wie in der Spur belegt).

Irgendwelche Ideen?

+0

Sieht aus wie Problem auf MySql Seite ist. - Welche Speicher-Engine haben Sie verwendet? - Verwenden Sie MyISAM (das die referenzielle Integrität nicht unterstützt)? - Haben Sie es mit sqlite von postgresql versucht? –

+0

Ähnliche Frage hier: http: // stackoverflow.com/questions/1600129/using-süd-zu-refactor-a-django-modell-mit-vererbung –

Antwort

4

Update, um das alte Feld löschen mit mysql-5.5.30-1.fc18.x86_64 und

MySQL-python==1.2.4 
Django==1.4.2 
South==0.7.6 

folgenden Werken:

Wie @Eloff kommentiert, kann South den ursprünglichen FK aus unbekannten Gründen nicht finden, aber es scheint nicht wichtig zu sein. Es gibt keine Notwendigkeit für eine Datenmigration (glaube ich), da pk Werte sich nicht ändern sollten.

Die Feldspezifikation (unter Verwendung von self.gf) wird aus Souths automatisch generierten Migrationen zur Konsistenz übernommen.

+1

Sie könnten von [diesem kleinen South Bug] (http://south.aeracode.org/ticket/1186) gebissen werden, wenn Sie diese Lösung verwenden. Entweder Affe-Patch Süd (siehe Ticket) oder Bestechung [Andrew] (http://aeracode.org), um es zu beheben – supervacuo

6

Wenn Sie eine ForeignKey umbenennen, denken Sie daran, am Ende des Feldnamens, den Sie in Django verwenden, _id hinzuzufügen. Z.B.

db.rename_column('accounts_transaction', 'operator_id', 'responsible_id') 

Und nicht

db.rename_column('accounts_transaction', 'operator', 'responsible') 

Aber ich habe nur getestet dies auf SQLite (die gar nicht wirklich die ALTER_TABLE haben), so dass ich weiß nicht, ob es tatsächlich auf mysql funktioniert/postgres.

24

Zuerst müssen Sie den Namen der Datenbankspalte nicht im Modell verwenden. ZB: foobar_id nicht foobar.

Dann müssen Sie die fk Zwänge fallen zu lassen und sie nach Umbenennung neu:

db.drop_foreign_key('app_model', 'old_id') 
db.rename_column('app_model', 'old_id', 'new_id') 
db.alter_column('app_model', 'new_id', models.ForeignKey(to=orm['app.OtherModel'])) 

Wenn Ihr fk nullable ist, dass Sie es verwenden müssen, ändern:

db.alter_column('app_model', 'new_id', models.ForeignKey(null=True, to=orm['app.OtherModel'])) 
+1

Dies funktioniert nicht mit MySQL 5.5.13 (Süden 0.7.3) drop_foreign_key findet die Fremdschlüssel-Constraint nicht. – Eloff

+0

Sollte alter_column() nicht 'new_id' verwenden? – del

+0

Das ist wirklich schwierig zu debuggen, wenn das fk Nullable ist. Danke Mann –

11

MySQL-Benutzer sollte sein Kenntnis von diesem Fehler in Süden, es gilt auch, wenn in der Tat nach wie vor:

http://south.aeracode.org/ticket/697

Die Abhilfe ist die Migration in 3 Schritten durchzuführen:

1) Neuen Feld

2) Daten, die die Daten in das neue Feld wandern

3)

+0

IMHO, das ist die einzige Lösung, die zuverlässig mit MySQL DBs funktioniert –

Verwandte Themen