如何用South重命名外键字段?

GJ.*_*GJ. 13 django django-south

重命名一个简单的charfield等似乎很容易(Django - 如何使用South重命名模型字段?)

但是,当我尝试在ForeignKey字段上使用相同的时候,我收到一个错误:

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

这源于迁移试图由于某种原因向后运行(如跟踪中所示).

有任何想法吗?

ion*_*lmc 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']))
Run Code Online (Sandbox Code Playgroud)

如果您的fk可以为空,则需要将其更改为:

db.alter_column('app_model', 'new_id', models.ForeignKey(null=True, to=orm['app.OtherModel']))
Run Code Online (Sandbox Code Playgroud)


小智 11

MySQL用户应该知道南方的这个错误,如果确实它仍然适用:

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

解决方法是通过3个步骤进行迁移:

1)添加新字段

2)数据将数据迁移到新字段

3)删除旧字段


小智 6

重命名时ForeignKey,请记住添加_id到Django中使用的字段名称的末尾.例如

db.rename_column('accounts_transaction', 'operator_id', 'responsible_id')
Run Code Online (Sandbox Code Playgroud)

并不是

db.rename_column('accounts_transaction', 'operator', 'responsible')
Run Code Online (Sandbox Code Playgroud)

但我只在sqlite上测试了这个(实际上根本没有ALTER_TABLE),所以我不知道它是否真的可以在mysql/postgres上运行.


sup*_*cuo 4

更新:与mysql-5.5.30-1.fc18.x86_64

MySQL-python==1.2.4
Django==1.4.2
South==0.7.6
Run Code Online (Sandbox Code Playgroud)

以下作品:

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']
                        ))
Run Code Online (Sandbox Code Playgroud)

正如@Eloff 评论的那样,South 由于未知原因找不到原始的 FK,但这似乎并不重要。不需要数据迁移(我相信),因为 pk 值不应改变。

为了保持一致性,字段规范(使用self.gf)取自 South 自动生成的迁移。