【发布时间】:2016-10-09 05:55:58
【问题描述】:
我们已经创建了一个大型 Django 应用程序,并且我们想要压缩迁移。但是,压缩迁移在我们应用程序中的应用程序之间具有循环依赖关系。我们如何在不破坏 Django 迁移压缩的情况下打破这些循环依赖关系?
我创建了一个small sample project 来重现该问题。该项目有两个应用程序:fruit 和 meat。一个Apple 有很多Bacon
孩子,Bacon 有很多 Cranberry 孩子。可以看到水果类app依赖于肉类app,肉类类app依赖于水果类app。
第一次提交创建了所有三个模型,每个模型都有一个名称字段,并且
从Cranberry 到Bacon 和从Bacon 到Apple 的外键。调用 makemigrations 会创建三个迁移:
-
fruit/0001_initial创建Apple和Cranberry模型 -
meat/0001_initial创建带有Apple外键的Bacon模型 -
fruit/0002_cranberry_bacon将外键从Cranberry添加到Bacon
下一次提交添加了一个 Apple.size 字段,这样就可以压缩一些东西了。
调用 makemigrations 添加另一个迁移:
-
fruit/0003_apple_size添加size字段
运行 squashmigrations 现在会创建一个具有循环依赖关系的压缩迁移。 squashmigrations documentation 给出了这样的建议:
要手动解析
CircularDependencyError,请将循环依赖循环中的一个 ForeignKey 分解为单独的迁移,并使用它移动对另一个应用程序的依赖。如果您不确定,请查看 makemigrations 在被要求从您的模型创建全新迁移时如何处理该问题。在 Django 的未来版本中,将更新 squashmigrations 以尝试自行解决这些错误。
但是,如果我这样做,则额外的迁移未正确配置为替代。这意味着我当前已经完成原始迁移的数据库尝试再次添加外键字段并失败。
$ ./manage.py migrate
...
django.db.utils.ProgrammingError: column "bacon_id" of relation "fruit_cranberry" already exists
如何告诉迁移系统两个新的迁移替换了所有旧的迁移?
【问题讨论】: