Django 1.8 迁移:有什么方法可以从不再有模型的数据库 table 中获取数据?
Django 1.8 migration: any way to get data from database table that no longer has a model?
我正在尝试重命名一个模型,我想以不依赖于在应用时仍然存在的旧名称的方式编写迁移。我能否以某种方式从迁移代码中不再具有模型的数据库 table 获取数据?
详情:
我有一个 Region
模型,我想将其移至更通用的 GeoObject
模型并从 models.py
中删除。如果我编写从现有 Regions
和 from models import Region
创建 GeoObjects
的迁移代码,我将必须保留 Region
模型,直到我的主数据库迁移。但我想编写一个迁移,以便它不依赖于存在的 Region
模型,只需检查数据库 table 是否存在并使用它。是否可以使用 Django instruments 来做到这一点,如果可能的话不依赖于特定的数据库类型?
是的,你可以。
但首先,你真的不应该在迁移中导入任何模型。
查看 RunPython
操作,这将允许您 运行 迁移中的任何 python 代码。 RunPython
将传递给您的函数 2 个参数:apps
和 schema_editor
。第一个参数包含应用该迁移阶段的模型结构,因此如果实际删除模型是在该迁移的后期,您仍然可以使用传递给函数的 apps
访问该模型。
假设您的模型如下所示:
class SomeModel(models.Model):
some_field = models.CharField(max_length=32)
现在您要删除该模型,自动创建的迁移将包含:
class Migration(migrations.Migration):
dependencies = [
('yourapp', '0001_initial'), # or any other dependencies
]
operations = [
migrations.DeleteModel(
name='Main',
),
]
您可以通过在 DeleteModel 操作上方注入 RunPython 来修改该迁移:
operations = [
migrations.RunPython(
move_data_to_other_model,
move_data_back, # for backwards migration - if you won't ever want to undo this migration, just don't pass that function at all
),
migrations.DeleteModel(
name='SomeModel',
),
]
并在迁移前创建 2 个函数 class:
def move_data_to_other_model(apps, schema_editor):
SomeModel = apps.get_model('yourapp', 'SomeModel')
for something in SomeModel.objects.all():
# do your data migration here
o = OtherModel.objects.get(condition=True)
o.other_field = something.some_field
def move_data_back(apps, schema_editor):
SomeModel = apps.get_model('yourapp', 'SomeModel')
for something in OtherModel.objects.all():
# move back your data here
SomeModel(
some_field=something.other_field,
).save()
即使您的模型不再在 models.py 中定义也没关系,django 可以根据迁移历史重建该模型。但请记住:模型中的保存方法(和其他自定义方法)不会在迁移中被调用。此外,任何 pre_save 或 post_save 信号都不会被触发。
我正在尝试重命名一个模型,我想以不依赖于在应用时仍然存在的旧名称的方式编写迁移。我能否以某种方式从迁移代码中不再具有模型的数据库 table 获取数据?
详情:
我有一个 Region
模型,我想将其移至更通用的 GeoObject
模型并从 models.py
中删除。如果我编写从现有 Regions
和 from models import Region
创建 GeoObjects
的迁移代码,我将必须保留 Region
模型,直到我的主数据库迁移。但我想编写一个迁移,以便它不依赖于存在的 Region
模型,只需检查数据库 table 是否存在并使用它。是否可以使用 Django instruments 来做到这一点,如果可能的话不依赖于特定的数据库类型?
是的,你可以。
但首先,你真的不应该在迁移中导入任何模型。
查看 RunPython
操作,这将允许您 运行 迁移中的任何 python 代码。 RunPython
将传递给您的函数 2 个参数:apps
和 schema_editor
。第一个参数包含应用该迁移阶段的模型结构,因此如果实际删除模型是在该迁移的后期,您仍然可以使用传递给函数的 apps
访问该模型。
假设您的模型如下所示:
class SomeModel(models.Model):
some_field = models.CharField(max_length=32)
现在您要删除该模型,自动创建的迁移将包含:
class Migration(migrations.Migration):
dependencies = [
('yourapp', '0001_initial'), # or any other dependencies
]
operations = [
migrations.DeleteModel(
name='Main',
),
]
您可以通过在 DeleteModel 操作上方注入 RunPython 来修改该迁移:
operations = [
migrations.RunPython(
move_data_to_other_model,
move_data_back, # for backwards migration - if you won't ever want to undo this migration, just don't pass that function at all
),
migrations.DeleteModel(
name='SomeModel',
),
]
并在迁移前创建 2 个函数 class:
def move_data_to_other_model(apps, schema_editor):
SomeModel = apps.get_model('yourapp', 'SomeModel')
for something in SomeModel.objects.all():
# do your data migration here
o = OtherModel.objects.get(condition=True)
o.other_field = something.some_field
def move_data_back(apps, schema_editor):
SomeModel = apps.get_model('yourapp', 'SomeModel')
for something in OtherModel.objects.all():
# move back your data here
SomeModel(
some_field=something.other_field,
).save()
即使您的模型不再在 models.py 中定义也没关系,django 可以根据迁移历史重建该模型。但请记住:模型中的保存方法(和其他自定义方法)不会在迁移中被调用。此外,任何 pre_save 或 post_save 信号都不会被触发。