创建新字段后,无法使用 RunPython 在迁移中获取模型记录



问题:

  1. 我创建了一个名为">new_field";在我的模型MyModel中01";它添加了这个字段。在那之后,我想改变关于一些旧字段的模型记录">old_field";在新的迁移中">02">
  2. 所以我创建了迁移"02〃使用RunPython更改我的记录,它可能看起来像这样:

from ..models import MyModel
def update_model():
for record in MyModel.objects.all():
record.new_field = record.old_field
record.save()
class Migration(migrations.Migration):
dependencies = [('myapp', '01')]
operation = [migrations.RunPython(update_model, lambda *args: None)]

这个迁移会运行得很好,但之后我想创建新的字段">super_new_field":

  1. 我正在创建迁移">03";其创建新的字段">super_new_field">

一切都会好起来的。但若我清除数据库,然后运行迁移,迁移">02";将不起作用,因为它正试图访问MyModelsuper_new_field";在Django中,但自从迁移以来,它在数据库中仍然缺失03";尚未执行。这意味着";def update_model";必须删除(或者必须更改迁移顺序和其他所有内容(才能在新环境上执行迁移,这不是一个好的

问题:

有没有一种方法可以在迁移中更新模型记录并避免这个问题?迁移似乎是一个很好的地方,因为我只需要在执行迁移后更新一次记录,但如果我要创建新的字段和迁移,那么以前尝试访问模型记录的迁移将无法工作,因为字段丢失了。

关于数据迁移的文档描述了我们在迁移过程中需要使用历史模型,因为直接导入的模型可能是比迁移预期的新的版本。CCD_ 1将两个参数appsschema_editor传递给被调用的函数。其中,我们可以使用apps来获得历史模型:

def update_model(apps, schema_editor):
MyModel= apps.get_model('yourappname', 'MyModel')
for record in MyModel.objects.all():
record.new_field = record.old_field
record.save()
class Migration(migrations.Migration):
dependencies = [('myapp', '01')]
# Don't use `lambda *args: None` just pass `RunPython.noop` instead
operation = [migrations.RunPython(update_model, migrations.RunPython.noop)]

最新更新