【问题标题】:How to rename a foreignkey field with South?如何用 South 重命名外键字段?
【发布时间】:2011-03-29 22:46:45
【问题描述】:

重命名一个简单的字符域等似乎很容易 (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")

这源于迁移尝试出于某种原因向后运行(如跟踪所示)。

有什么想法吗?

【问题讨论】:

  • 看起来问题出在 MySql 方面。 - 你用的是什么存储引擎? - 你使用 MyISAM(不支持参照完整性)吗? - 你用 postgresql 的 sqlite 试过了吗?

标签: django django-south


【解决方案1】:

首先,您需要使用 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']))

【讨论】:

  • 这不适用于 MySQL 5.5.13 (south 0.7.3) drop_foreign_key 找不到外键约束。
  • 不应该 alter_column() 使用 'new_id' 吗?
  • 如果 fk 可以为空,那真的很难调试。谢谢大佬
  • 我认为这确实应该是公认的答案。非常适合我。
【解决方案2】:

如果它确实仍然适用,那么 MySQL 用户应该注意南方的这个错误:

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

解决方法是分 3 步进行迁移:

1) 添加新字段

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

3) 删除旧字段

【讨论】:

  • 恕我直言,这是唯一能与 MySQL 数据库可靠工作的解决方案
【解决方案3】:

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

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

不是

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

但我只在 sqlite 上测试过(实际上根本没有 ALTER_TABLE),所以我不知道它是否真的可以在 mysql/postgres 上工作。

【讨论】:

    【解决方案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 cmets,South 由于未知原因找不到原始FK,但这似乎并不重要。不需要数据迁移(我相信),因为 pk 值不应该改变。

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

    【讨论】:

    • 如果您使用此解决方案,您可能会被this little South bug 咬伤。要么猴子补丁南(见票)或贿赂Andrew修复它
    猜你喜欢
    • 2011-03-15
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 2011-01-30
    • 2011-11-21
    • 1970-01-01
    • 2011-09-05
    • 2019-04-02
    相关资源
    最近更新 更多