重命名一个简单的字段等似乎很容易(Django - How to rename a model field using South?)
然而,当我在ForeignKey字段上尝试使用相同的内容时,我收到错误:
_mysql_exceptions.OperationalError: (1091, "Can't DROP '[new_fkey_field_name]'; check that column/key exists")
这源于因某种原因尝试向后运行 的迁移(如跟踪中所示)。
有什么想法吗?
答案 0 :(得分:24)
首先,您需要使用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']))
答案 1 :(得分:11)
MySQL用户应该知道南方的这个错误,如果确实它仍然适用:
http://south.aeracode.org/ticket/697
解决方法是通过3个步骤进行迁移:
1)添加新字段
2)数据将数据迁移到新字段
3)删除旧字段
答案 2 :(得分:6)
重命名ForeignKey
时,请记住将_id
添加到您在Django中使用的字段名称的末尾。 E.g。
db.rename_column('accounts_transaction', 'operator_id', 'responsible_id')
而不是
db.rename_column('accounts_transaction', 'operator', 'responsible')
但是我只在sqlite上测试了这个(实际上根本没有ALTER_TABLE),所以我不知道它是否真的可以在mysql / postgres上运行。
答案 3 :(得分:4)
更新:使用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
)取自South自动生成的迁移以保持一致性。