【发布时间】:2015-06-17 00:29:58
【问题描述】:
让我们想象一个简化的 Django 项目:
<root>/lib/python2.7/site-packages/externalapp/shop
<root>/myapp
myapp 还通过添加一些字段来扩展externalapp.shop.models 模型。 manage.py makemigrations 确实生成了名为 0004_auto_20150410_2001.py 的架构迁移文件:
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
# __init__ is added by me as an attempt how to tell django's
# migration loader operations are for the different application
def __init__(self, name, app_label):
super(Migration, self).__init__(name, 'shop')
dependencies = [
('myapp', '__first__'),
('shop', '0003_auto_20150408_0958'),
]
operations = [
migrations.AddField(
model_name='product',
name='vat',
field=models.ForeignKey(to='myapp.VAT', null=True),
),
]
如果上述迁移架构默认放在<root>/lib/python2.7/site-packages/externalapp/shop/migrations/路径下,manage.py migrate成功,表字段添加正确。
但是,如果我确实将上述迁移文件移动到 myapp/migrations/,manage.py migrate 之后会失败
django.core.management.base.CommandError:检测到迁移冲突(myapp 中的 0001_initial、0004_auto_20150410_2001)。 要修复它们,请运行“python manage.py makemigrations --merge”
错误消息我不太明白,建议 makemigrations --merge 失败并符合预期:
ValueError: 找不到集合的共同祖先([u'0001_initial', u'0004_auto_20150410_2001'])
我尝试覆盖 migrations.Migration.__init__ 以更改派生的 app_label 但似乎迁移加载程序忽略了它。
如何调整迁移文件使其可以在其他应用程序中运行?
原因是在生产中externalapp 源不能直接接触,是只读的。
【问题讨论】:
-
如何将字段从自己的应用程序添加到外部应用程序?这听起来像是一场潜在的灾难。至于迁移,单个应用程序中的所有迁移必须形成从第一个迁移到最后一个迁移的单一、无分支的路径。您有两个用于迁移的端点。您应该将
('myapp', '__first__')依赖项更改为依赖于myapp中的最后一次迁移。 -
@knbk 感谢您的提示。它修复了冲突的迁移错误,但新增了 state.models[app_label, self.model_name_lower].fields.append((self.name, field)) KeyError: (u'myapp', u'product') i> 出现。对于这个特定的迁移,如何明确告诉 django/south 它应该在
externalapp.shop而不是myapp上运行? 添加来自其他应用程序的一些字段,如果您知道自己在做什么,不必是一场灾难,甚至是更简单、更快的解决方案(无需额外的表和 sql 连接)。 Related blog 关于。 -
更新:我确实删除了数据库,取消注释迁移初始化程序并重新运行所有迁移,它开始工作!谢谢。
标签: python django django-models django-admin