简体   繁体   English

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

[英]Django data migration fails when running manage.py test, but not when running manage.py migrate

I have a Django 1.7 migration that looks something like this: 我有一个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',
        ),
    ]

When I run manage.py migrate , it migrates just fine. 当我运行manage.py migrate ,它会很好地迁移。 When I run manage.py test , however, it tries to create the test database, then fails in the middle of this migration with the following error: 但是,当我运行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'")

When I connect to the test database afterwards (it doesn't delete it), the database structure looks as you'd expect after the migration has run, even though it crashed half way through. 当我之后连接到测试数据库(它不会删除它)时,数据库结构看起来就像迁移运行后所期望的那样,即使它在中途崩溃了。 What's going on here? 这里发生了什么?

Edit: I've tried splitting the migration into three separate migrations, one containing all the stuff before the RunPython one, one containing RunPython on its own, and one containing all the stuff that's afterwards; 编辑:我尝试将迁移拆分为三个单独的迁移,一个包含RunPython之前的所有内容,一个包含RunPython ,另一个包含之后的所有内容; it's still doing the exact same thing. 它仍在做同样的事情。

This is kind of weird and we don't know why this works, but we changed our allow_migrate signature in our router to the following: allow_migrate ,我们不知道为什么会这样,但我们将路由器中的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

And this error mysteriously went away. 这个错误神秘地消失了。 Note that this signature does not match what is in the 1.8 documentation (we're using 1.8.2) allow_migrate(db, app_label, model_name=None, **hints) as shown here: https://docs.djangoproject.com/en/1.8/topics/db/multi-db/#allow_migrate 请注意,此签名与1.8文档中没有匹配(我们使用的是1.8.2) allow_migrate(db, app_label, model_name=None, **hints) ,如下所示: httpsallow_migrate(db, app_label, model_name=None, **hints) EN / 1.8 /主题/ DB /多分贝/#allow_migrate

But hopefully this will help you? 但希望这对你有帮助吗?

It turns out, the migrations were running successfully, in the order they were supposed to, but I have two databases, and it was running my migrations on both without consulting the database router. 事实证明,迁移是按照它们应该的顺序成功运行的,但是我有两个数据库,它在没有咨询数据库路由器的情况下运行我的迁移。 The Django ticket to track this problem is #23273 , which is still open. 用于跟踪此问题的Django票是#23273 ,它仍处于打开状态。

Presumably, the RunPython migration was querying against default (which had already been migrated) rather than the database the migration was actually supposed to run on. 据推测, RunPython迁移是针对default (已经迁移)而不是迁移实际应该运行的数据库进行查询。

In my case, we no longer needed to use the second database for anything, so we were able to remove it from settings.DATABASES altogether. 在我的情况下,我们不再需要使用第二个数据库,因此我们可以将它从settings.DATABASES删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM