我正在使用South和我的Django应用程序。我有两个模型,我从ForeignKey
关系变为OneToOneField
关系。当我在我的dev数据库上运行此迁移时,它运行正常。当迁移作为创建测试数据库的一部分运行时,最新的迁移失败,出现MySQL 1005错误:“无法创建表mydb。#sql-3249_1d(错误号:121)”。做一些谷歌搜索显示,这通常是尝试添加与现有约束具有相同名称的约束的问题。它失败的迁移中的特定行是:
关系改变自:
class MyModel(models.Model):
othermodel = models.ForeignKey(OtherModel)
到
class MyModel(models.Model):
othermodel = models.OneToOneField(OtherModel)
在迁移中生成以下语句:
db.alter_column('myapp_mymodel', 'othermodel_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['myapp.OtherModel'], unique=True))
db.create_unique('myapp_mymodel', ['othermodel_id'])
但是create_unique
来电失败,而alter_column
来电失败了。我运行以下命令来查看正在生成的SQL:
python manage.py migrate myapp 0010 --db-dry-run --verbosity=2
并打印出来
myapp:0010_auto__chg_field_mymodel_othermodel__add_unique_mymodel
= ALTER TABLE `myapp_mymodel` ADD CONSTRAINT `myapp_mymodel_othermodel_id_uniq` UNIQUE (`othermodel_id`) []
= SET FOREIGN_KEY_CHECKS=1; []
= ALTER TABLE `myapp_mymodel` ADD CONSTRAINT `myapp_mymodel_othermodel_id_uniq` UNIQUE (`othermodel_id`) []
它试图运行ADD CONSTRAINT
两次似乎很奇怪,但是如果我删除了db.create_unique
调用,那么当我用--db-dry-run
运行时没有生成SQL,但我仍然如果我真的运行它会得到错误。
我在这里不知所措,感谢任何帮助。
答案 0 :(得分:11)
您实际上根本不需要迁移。 OneToOne和ForeignKey关系在钩子下有一个兼容的数据库模式:一个简单的列,其中一个表中包含另一个对象ID。
如果您不想告诉南方忽略此更改,请假装使用migrate --fake
进行迁移。
答案 1 :(得分:1)
我同意@ e-satisf,这里的目标是假冒迁移,但如果您与团队合作,我建议采用不同的方法。
如果您创建迁移,然后--fake
,则您的所有团队成员都需要记住--fake
它。如果他们中的任何人在升级时没有这样做,那你就麻烦了。
更好的方法是创建一个空迁移,然后迁移它:
manage.py schemamigration yourapp --empty fake_migration_of_foreign_key_to_onetoone
manage.py migrate # Like you always do!
答案 2 :(得分:0)
我要尝试的第一件事就是在不同的地方添加一个db.delete_unique(...)
,看看我是否可以破解它。
如果做不到这一点,我会把它分成3次迁移: