python - 其他应用程序中的 Django 迁移文件?

标签 python django django-models django-admin

让我们想象一下以下简化的 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),
        ),
    ]

如果上面的迁移schema放在<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资源不能直接接触,是只读的。

最佳答案

要围绕 Django 项目移动迁移文件,就像注入(inject)其他应用程序模型的情况一样,您需要确保在您的 django.db.migrations.Migration 后代中:

  • 显式设置应用程序名称,因为迁移加载器由迁移文件所在的应用程序自动派生它,否则会尝试在不同模型上执行操作
  • 通知迁移记录器它为其他应用程序提供迁移,否则它仍会将迁移视为未应用(有关已应用迁移的记录存储在一个表中,当前名为 django_migrations)

我已经解决了迁移初始化程序中的问题,它可能看起来像:

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]),)

它确实对我有用,并且发现它是足够通用的方式。

如果可能,渴望听到更好/更简单的解决方案。

关于python - 其他应用程序中的 Django 迁移文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29575802/

相关文章:

python - 如何在python中拼接文件夹中的图像

python - 同步目录树算法辅助

python - 导入错误 : module incorrectly imported

django - 如何调整 celery 设置,使 Redis 不使用太多内存? celery 任务 RESULT_EXPIRES?

python - 如何在 django 模型实例中转换 json?

python - 使用 django-allauth 保存自定义用户模型

python - 如何在 Dexterity 中传递数据网格字段中选择字段的列表值?

python - 用 "#"替换字母并反转

Django 'model' 对象不可迭代

python - 检查一个项目是否包含在 ManyToManyField (django)