Django数据迁移失败,除非单独运行
Django data migration fails unless it's run separately
我已经 运行 参与过几次,但无法弄清楚为什么会这样。当我 运行 迁移全部通过 ./manage.py migrate
时,最后一次迁移(数据迁移)失败。解决方案是 运行 在其他迁移完成后自行进行数据迁移。我怎样才能 运行 它们全部自动没有错误?
我有一系列的迁移:
- fulfillment/0001.py
- order/0041.py(依赖:fulfillment/0001.py)
- order/0042.py
- order/0043.py
我遵循了这个 RealPython article to move a model to a new app ,它工作得很好并且包含在迁移 #1 到 #3 中。迁移 #3 还添加了一个 GenericForeignKey
字段。迁移 #4 是一个数据迁移,它只是从现有的 ForeignKey
字段填充 GenericForeignKey
字段。
from django.db import migrations, models
def copy_to_generic_fk(apps, schema_editor):
ContentType = apps.get_model('contenttypes.ContentType')
Order = apps.get_model('order.Order')
pickup_point_type = ContentType.objects.get(
app_label='fulfillment',
model='pickuppoint'
)
Order.objects.filter(pickup_point__isnull=False).update(
content_type=pickup_point_type,
object_id=models.F('pickup_point_id')
)
class Migration(migrations.Migration):
dependencies = [
('order', '0042'),
]
operations = [
migrations.RunPython(copy_to_generic_fk, reverse_code=migrations.RunPython.noop)
]
运行 序列在一起我得到一个错误:
fake.DoesNotExist: ContentType matching query does not exist.
如果我 运行 迁移到 #3 然后 运行 #4 本身一切正常。我怎样才能让它们按顺序到达 运行 而没有错误?
有两件事可能会解决问题,首先查看 run_before
https://docs.djangoproject.com/en/3.1/howto/writing-migrations/#controlling-the-order-of-migrations
如果您将它添加到 fulfillment #1,并确保它在订单 #4 之前运行,它应该可以解决问题。
您可以做的另一件事是将您的数据迁移移动到 fulfillment #2,这样您就可以确定所有订单都已完成并且 fulfillment #1 也已完成。
不是通过 .get()
获取 ContentType
,而是必须通过 apps
参数检索模型,然后使用 get_for_model()
.
def copy_to_generic_fk(apps, schema_editor):
ContentType = apps.get_model('contenttypes', 'ContentType')
PickupPoint = apps.get_model('fulfillment', 'pickuppoint')
pickup_point_type = ContentType.objects.get_for_model(PickupPoint)
...
我已经 运行 参与过几次,但无法弄清楚为什么会这样。当我 运行 迁移全部通过 ./manage.py migrate
时,最后一次迁移(数据迁移)失败。解决方案是 运行 在其他迁移完成后自行进行数据迁移。我怎样才能 运行 它们全部自动没有错误?
我有一系列的迁移:
- fulfillment/0001.py
- order/0041.py(依赖:fulfillment/0001.py)
- order/0042.py
- order/0043.py
我遵循了这个 RealPython article to move a model to a new app ,它工作得很好并且包含在迁移 #1 到 #3 中。迁移 #3 还添加了一个 GenericForeignKey
字段。迁移 #4 是一个数据迁移,它只是从现有的 ForeignKey
字段填充 GenericForeignKey
字段。
from django.db import migrations, models
def copy_to_generic_fk(apps, schema_editor):
ContentType = apps.get_model('contenttypes.ContentType')
Order = apps.get_model('order.Order')
pickup_point_type = ContentType.objects.get(
app_label='fulfillment',
model='pickuppoint'
)
Order.objects.filter(pickup_point__isnull=False).update(
content_type=pickup_point_type,
object_id=models.F('pickup_point_id')
)
class Migration(migrations.Migration):
dependencies = [
('order', '0042'),
]
operations = [
migrations.RunPython(copy_to_generic_fk, reverse_code=migrations.RunPython.noop)
]
运行 序列在一起我得到一个错误:
fake.DoesNotExist: ContentType matching query does not exist.
如果我 运行 迁移到 #3 然后 运行 #4 本身一切正常。我怎样才能让它们按顺序到达 运行 而没有错误?
有两件事可能会解决问题,首先查看 run_before
https://docs.djangoproject.com/en/3.1/howto/writing-migrations/#controlling-the-order-of-migrations
如果您将它添加到 fulfillment #1,并确保它在订单 #4 之前运行,它应该可以解决问题。
您可以做的另一件事是将您的数据迁移移动到 fulfillment #2,这样您就可以确定所有订单都已完成并且 fulfillment #1 也已完成。
不是通过 .get()
获取 ContentType
,而是必须通过 apps
参数检索模型,然后使用 get_for_model()
.
def copy_to_generic_fk(apps, schema_editor):
ContentType = apps.get_model('contenttypes', 'ContentType')
PickupPoint = apps.get_model('fulfillment', 'pickuppoint')
pickup_point_type = ContentType.objects.get_for_model(PickupPoint)
...