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

发布于 2024-09-14 12:39:25 字数 409 浏览 10 评论 0原文

重命名一个简单的 charfield 等似乎很容易(Django - How to rename a使用 South 的模型字段?

但是,当我尝试在外键字段上使用相同的字段时,我收到错误:

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

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

有什么想法吗?

Renaming a simple charfield etc seems easy (Django - How to rename a model field using South?)

However when I try using the same on a ForeignKey field I get an error:

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

Which stems from the migration trying to run the backwards for some reason (as evidenced in the trace).

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

莫多说 2024-09-21 12:39:25

首先,您需要使用数据库列名称而不是模型中的列名称。例如: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']))

First, you need to use the db column name not the one in the model. Eg: foobar_id not foobar.

Then you need to drop the fk constraints and recreate them after renaming:

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']))

If your fk is nullable you need to use change it to:

db.alter_column('app_model', 'new_id', models.ForeignKey(null=True, to=orm['app.OtherModel']))
星軌x 2024-09-21 12:39:25

MySQL 用户应该注意南部的这个错误,如果它确实仍然存在的话:

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

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

1)添加新字段

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

3)删除旧字段

MySQL users ought to be aware of this bug in south, if indeed it still applies:

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

The workaround is to conduct the migration in 3 steps:

1) Add new field

2) data migrate the data to the new field

3) delete the old field

与酒说心事 2024-09-21 12:39:25

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

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

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

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

When renaming a ForeignKey, remember to add _id to the end of the field name you use in Django. E.g.

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

And not

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

But I have only tested this on sqlite (which don't actually have the ALTER_TABLE at all), so I don't know if it will actually work on mysql/postgres.

我还不会笑 2024-09-21 12:39:25

更新:使用 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 评论,South 由于未知原因找不到原始 FK,但似乎并没有事情。不需要数据迁移(我相信),因为 pk 值不应改变。

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

Update: with mysql-5.5.30-1.fc18.x86_64 and

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

the following works:

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']
                        ))

As @Eloff comments, South can't find the original FK for reasons unknown, but it doesn't seem to matter. There is no need for a data migration (I believe) as pk values should not change.

The field specification (using self.gf) is taken from South's auto-generated migrations for consistency.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文