问题描述
让我们想象以下简化的 Django 项目:
Let's imagine a following simplified Django project:
<root>/lib/python2.7/site-packages/externalapp/shop
<root>/myapp
myapp
还通过添加一些字段来扩展 externalapp.shop.models
模型.manage.py makemigrations
确实生成了以下名为 0004_auto_20150410_2001.py 的架构迁移文件:
myapp
also extends externalapp.shop.models
models by adding a few fields. manage.py makemigrations
did generated following schema migration file called 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),
),
]
如果上面的迁移schema默认放在/lib/python2.7/site-packages/externalapp/shop/migrations/
路径下,manage.py migrate
成功,表字段添加正确.
If the above migration schema is placed in <root>/lib/python2.7/site-packages/externalapp/shop/migrations/
path by default, manage.py migrate
succeeds and table fields are correctly added.
但是,如果我确实将上面的迁移文件移动到 myapp/migrations/
,下面的 manage.py migrate
会失败并显示
However if I do move the above migration file into myapp/migrations/
, following manage.py migrate
fails with
django.core.management.base.CommandError:检测到冲突的迁移(0001_initial、0004_auto_20150410_2001 in myapp).要修复它们,请运行python manage.py makemigrations --merge"
我不太明白的错误消息并建议 makemigrations --merge
失败并预期:
error message I can't quite understand and suggested makemigrations --merge
fails with expected:
ValueError: 找不到集合的共同祖先([u'0001_initial', u'0004_auto_20150410_2001'])
我试图覆盖 migrations.Migration.__init__
来改变派生的 app_label
但似乎迁移加载程序忽略了它.
I've tried to override migrations.Migration.__init__
to alter derived app_label
but seems migration loader ignores it.
如何调整迁移文件使其可以从其他应用程序工作?原因是在生产中 externalapp
源不能直接接触,是只读的.
How adjust migration file so it can work from other application ?The reason is in production externalapp
sources can't be directly touched, are read only.
推荐答案
要在 Django 项目中移动迁移文件,例如注入其他应用程序的模型,您需要在 django.db 中确保.migrations.Migration
后代:
To move a migration file around a Django project, like in case of injecting models of other applications, you need to ensure in your django.db.migrations.Migration
descendant:
- 显式设置应用程序名称,因为迁移加载程序由迁移文件所在的应用程序自动派生,否则将尝试在不同模型上执行操作
- 通知迁移记录器它为其他应用程序提供迁移,否则它仍将认为迁移未应用(有关已应用迁移的记录存储在一个表中,当前名为
django_migrations
)
我已经解决了迁移初始值设定项中的问题,它可能如下所示:
I've solved the issue in migration initializer which may look like:
from django.db import migrations
TARGET_APP = 'shop' # application label migration is for
class Migration(migrations.Migration):
def __init__(self, name, app_label):
# overriding application operated upon
super(Migration, self).__init__(name, TARGET_APP)
# specify what original migration file it replaces
# or leave migration loader confused about unapplied migration
replaces = ((TARGET_APP, __module__.rsplit('.', 1)[-1]),)
它确实对我有用,并且找到了足够通用的方式.
It does work for me and find it enough generic way.
如果可能,渴望听到更好/更简单的解决方案.
Eager to hear about a better/simpler solution if possible.
这篇关于其他应用程序中的 Django 迁移文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!