运行 manage.py 测试时 Django 数据迁移失败,但 运行 manage.py 迁移时不会
Django data migration fails when running manage.py test, but not when running manage.py migrate
我有一个看起来像这样的 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
独立的,一个包含所有之后的东西;它仍然在做同样的事情。
事实证明,迁移 运行ning 成功,按照它们应该的顺序,但我有两个数据库,并且 运行ning 我的迁移没有咨询数据库路由器。跟踪此问题的 Django 票是 #23273,它仍然开放。
据推测,RunPython
迁移正在查询 default
(已经迁移),而不是迁移实际上应该 运行 的数据库。
就我而言,我们不再需要将第二个数据库用于任何事情,因此我们能够将其从 settings.DATABASES
中完全删除。
这有点奇怪,我们不知道为什么会这样,但我们将路由器中的 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
但希望这对您有所帮助?
我在 Django 3.1.5 上遇到了同样的问题。我最初使用设置文件中的 MIGRATION_MODULES 标志禁用了第一个应用程序的测试迁移。
MIGRATION_MODULES = {
'app1': None
}
我最终通过禁用第二个应用程序的迁移解决了测试问题
MIGRATION_MODULES = {
'app1': None,
'app2': None
}
我有一个看起来像这样的 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
独立的,一个包含所有之后的东西;它仍然在做同样的事情。
事实证明,迁移 运行ning 成功,按照它们应该的顺序,但我有两个数据库,并且 运行ning 我的迁移没有咨询数据库路由器。跟踪此问题的 Django 票是 #23273,它仍然开放。
据推测,RunPython
迁移正在查询 default
(已经迁移),而不是迁移实际上应该 运行 的数据库。
就我而言,我们不再需要将第二个数据库用于任何事情,因此我们能够将其从 settings.DATABASES
中完全删除。
这有点奇怪,我们不知道为什么会这样,但我们将路由器中的 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
但希望这对您有所帮助?
我在 Django 3.1.5 上遇到了同样的问题。我最初使用设置文件中的 MIGRATION_MODULES 标志禁用了第一个应用程序的测试迁移。
MIGRATION_MODULES = {
'app1': None
}
我最终通过禁用第二个应用程序的迁移解决了测试问题
MIGRATION_MODULES = {
'app1': None,
'app2': None
}