Django 1.8 迁移:有啥方法可以从不再有模型的数据库表中获取数据?
Posted
技术标签:
【中文标题】Django 1.8 迁移:有啥方法可以从不再有模型的数据库表中获取数据?【英文标题】:Django 1.8 migration: any way to get data from database table that no longer has a model?Django 1.8 迁移:有什么方法可以从不再有模型的数据库表中获取数据? 【发布时间】:2015-11-19 04:13:19 【问题描述】:我正在尝试重命名模型,并且我希望以不依赖于在应用时仍然存在的旧名称的方式编写迁移。我能否以某种方式从迁移代码中不再有模型的数据库表中获取数据?
详情:
我有一个Region
模型,我想将它移入一个更通用的GeoObject
模型并从models.py
中删除。如果我编写迁移代码,从现有的Regions
和from models import Region
创建GeoObjects
,我将不得不保留Region
模型,直到我的主数据库迁移。但我想编写一个迁移,以便它不依赖于存在的Region
模型,只需检查数据库表是否存在并使用它。如果可能的话,是否可以使用 Django 工具而不依赖于特定的数据库类型来做到这一点?
【问题讨论】:
【参考方案1】:是的,你可以。
但首先,您确实不应该在迁移中导入任何模型。
查看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 个函数:
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 信号。
【讨论】:
谢谢,感谢您的努力,但我如何编写代码来在迁移中创建新实例?是的,我已经在使用RunPython
,而且我什至不知道其他方法,有吗?无论如何,问题是我还不知道如何访问没有模型的数据库表。我已经从models.py
中删除了模型。我将通过链接重新检查文档,谢谢。
apps
传入你的函数并不依赖于你的models.py。这取决于迁移历史。该模型状态是由已经执行的迁移操作构建的,因此如果从数据库中删除模型的操作稍后在迁移中进行,则该模型仍可使用apps
。查看更新的答案。
完美。非常感谢。以上是关于Django 1.8 迁移:有啥方法可以从不再有模型的数据库表中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章
将旧 (Django 0.97) 模型数据导入/迁移到 Django 1.8 或更高版本
使用 --fake 后如何在 django 1.8 上重做迁移