本文介绍了其他应用程序中的 Django 迁移文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们想象以下简化的 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 迁移文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-16 12:36
查看更多