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

时间:2021-12-31 18:04:18

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. 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 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'")

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; it's still doing the exact same thing.

编辑:我尝试将迁移拆分为三个单独的迁移,一个包含RunPython之前的所有内容,一个包含RunPython,另一个包含之后的所有内容;它仍在做同样的事情。

2 个解决方案

#1


2  

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签名更改为以下内容:

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,**提示),如下所示:https://docs.djangoproject.com/ EN / 1.8 /主题/ DB /多分贝/#allow_migrate

But hopefully this will help you?

但希望这对你有帮助吗?

#2


0  

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迁移是针对默认(已经迁移)而不是迁移实际应该运行的数据库进行查询。

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中删除。

#1


2  

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签名更改为以下内容:

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,**提示),如下所示:https://docs.djangoproject.com/ EN / 1.8 /主题/ DB /多分贝/#allow_migrate

But hopefully this will help you?

但希望这对你有帮助吗?

#2


0  

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迁移是针对默认(已经迁移)而不是迁移实际应该运行的数据库进行查询。

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中删除。