我有一个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
,一个包含所有后来的东西;它还在做同样的事情。
答案 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
}