运行manage.py测试时,Django数据迁移失败,但运行manage.py migrate时却没有

时间:2015-03-19 05:59:43

标签: python django unit-testing django-testing django-migrations

我有一个Django 1.7迁移,看起来像这样:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

def units_to_m2m(apps, schema_editor):
    Interval = apps.get_model("myapp", "Interval")
    IntervalUnit = apps.get_model("myapp", "IntervalUnit")

    for interval in Interval.objects.all():
        IntervalUnit(
            interval=interval,
            unit=interval.unit,
            base_date=interval.base_date
        ).save()

class Migration(migrations.Migration):

    dependencies = [
        ('otherapp', '0007_auto_20150310_1400'),
        ('myapp', '0009_auto_20150316_1608'),
    ]

    operations = [
        migrations.CreateModel(
            name='IntervalUnit',
            # ...
        ),
        # ...
        migrations.AddField(
            model_name='interval',
            name='units',
            field=models.ManyToManyField(to='otherapp.Unit', through='myapp.IntervalUnit'),
            preserve_default=True,
        ),
        migrations.RunPython(units_to_m2m),
        migrations.RemoveField(
            model_name='interval',
            name='unit',
        ),
        migrations.RemoveField(
            model_name='interval',
            name='base_date',
        ),
    ]

当我运行manage.py migrate时,它移植得很好。但是,当我运行manage.py test时,它会尝试创建测试数据库,然后在迁移过程中失败并出现以下错误:

Traceback (most recent call last):
...
  File "/home/adam/myproject/myapp/migrations/0010_auto_20150317_1516.py", line 10, in units_to_m2m
    for interval in Interval.objects.all():
...
django.db.utils.OperationalError: (1054, "Unknown column 'myapp_interval.base_date' in 'field list'")

当我之后连接到测试数据库(它没有删除它)时,数据库结构看起来就像你在迁移运行后所期望的那样,即使它已经中途崩溃了。这里发生了什么?

修改:我已尝试将迁移拆分为三个单独的迁移,其中一个包含RunPython之前的所有内容,其中一个包含RunPython ,一个包含所有后来的东西;它还在做同样的事情。

3 个答案:

答案 0 :(得分:4)

这有点奇怪,我们不知道为什么会这样,但我们将路由器中的allow_migrate签名更改为以下内容:

def allow_migrate(self, db, app_label, **hints):
    """
    Make sure the mydb db does not allow migrations
    """
    if db == 'mydb':
        return False

    return True

这个错误神秘地消失了。请注意,此签名与1.8文档(我们使用1.8.2)allow_migrate(db, app_label, model_name=None, **hints)中的签名不符,如下所示:https://docs.djangoproject.com/en/1.8/topics/db/multi-db/#allow_migrate

但希望这会对你有帮助吗?

答案 1 :(得分:1)

事实证明,迁移是按照它们应该的顺序成功运行的,但是我有两个数据库,它在没有咨询数据库路由器的情况下运行我的迁移。用于跟踪此问题的Django票证是#23273,它仍处于打开状态。

据推测,RunPython迁移正在查询default(已经迁移过),而不是迁移实际应该运行的数据库。

就我而言,我们不再需要将第二个数据库用于任何事情,因此我们可以完全从settings.DATABASES中删除它。

答案 2 :(得分:0)

我在 Django 3.1.5 上遇到了同样的问题。我最初使用设置文件中的 MIGRATION_MODULES 标志禁用了第一个应用程序的测试迁移。

MIGRATION_MODULES = {
     'app1': None
}

我最终通过禁用第二个应用程序的迁移来解决测试问题

MIGRATION_MODULES = {
     'app1': None,
     'app2': None
}