Как переименовать поле foreignkey с South?
Переименование простого charfield и т.д. кажется легким (Django - как переименовать поле модели с помощью юга?)
Однако, когда я пытаюсь использовать то же самое в поле ForeignKey, я получаю сообщение об ошибке:
_mysql_exceptions.OperationalError: (1091, "Can't DROP '[new_fkey_field_name]'; check that column/key exists")
Это связано с миграцией, которая пытается по какой-то причине запустить обратную связь (как показано на трассе).
Любые идеи?
Ответы
Ответ 1
Обновление: с помощью mysql-5.5.30-1.fc18.x86_64
и
MySQL-python==1.2.4
Django==1.4.2
South==0.7.6
выполняются следующие работы:
class Migration(SchemaMigration_:
def forwards(self, orm):
db.rename_column('app_model', 'old_id', 'new_id')
db.alter_column('app_model', 'new_id',
self.gf('django.db.models.fields.related.ForeignKey')(
blank=True,
null=True,
to=orm['app.OtherModel']
))
def backwards(self, orm):
db.rename_column('app_model', 'new_id', 'old_id')
db.alter_column('app_model', 'old_id',
self.gf('django.db.models.fields.related.ForeignKey')(
blank=True,
null=True,
to=orm['app.OtherModel']
))
Как комментарии @Eloff, Юг не может найти оригинальный FK по неизвестным причинам, но это, похоже, не имеет значения. Нет необходимости в миграции данных (я считаю), поскольку значения pk не должны меняться.
Спецификация поля (используя self.gf
) берется из южных автогенерированных миграций для согласованности.
Ответ 2
Во-первых, вам нужно использовать имя столбца db, а не имя модели. Например: foobar_id не foobar.
Затем вам нужно отбросить ограничения fk и воссоздать их после переименования:
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']))
Если ваш fk является нулевым, вам нужно использовать его для изменения:
db.alter_column('app_model', 'new_id', models.ForeignKey(null=True, to=orm['app.OtherModel']))
Ответ 3
Пользователи MySQL должны знать об этой ошибке на юге, если она действительно применяется:
http://south.aeracode.org/ticket/697
Обходной путь состоит в том, чтобы выполнить миграцию в 3 этапа:
1) Добавить новое поле
2) данные переносят данные в новое поле
3) удалите старое поле
Ответ 4
При переименовании ForeignKey
не забудьте добавить _id
в конец имени поля, которое вы используете в Django. Например.
db.rename_column('accounts_transaction', 'operator_id', 'responsible_id')
И не
db.rename_column('accounts_transaction', 'operator', 'responsible')
Но я тестировал это только на sqlite (на самом деле у меня вообще нет ALTER_TABLE), поэтому я не знаю, действительно ли это будет работать с mysql/postgres.