我有一个正在使用的现有django网络应用程序。我必须从根本上将设计中的一个关键模型迁移到一个全新的设计,但我想缓存该模型的所有现有数据,并在准备部署时将它们迁移到生产中的新记录。
我有能力让我的网站在一晚上停留几个小时,并做我需要做的任何迁移。我可以通过哪些理智的方式进行迁移?
似乎任何迁移都需要: 1)将所有现有数据转储为某种格式,例如SQL,JSON,XML 2)将模型迁移到新格式 3)使用转换脚本将数据重新加载到新模型中
我还想过尝试将所有现有数据存储在名为“OldModel”的其他模型中(如果Model是现有模型的名称),然后实时迁移数据。
答案 0 :(得分:4)
有一个项目可以帮助我进行迁移,我听说过:South。
话虽如此,我承认我们没有使用它。我们仍然使用SQL语句文件来规划迁移。疯狂,我知道,但它具有可测试性的优势。在“大部署”之前,您可以在开发和暂存测试期间根据需要多次运行它。它可以是源控制,差异等。因此,它也可以从更大的部署脚本调用。当然,我们在运行之前备份生产: - )
如果您的数据库执行日记功能,则使用旧式方法具有额外的优势,即可以回滚事务历史记录。
我们使用JSON,XML和“OldModel”运行的实验 - > “NewModel”样式转储的扩展性很差。请注意,YMMV ......我们有一个相当大的数据库。通过使用脚本,您可以在生产数据库上运行,而无需卸载或重新加载大量数据。这样,即使是复杂的迁移也可能需要几秒钟而不是几小时。
答案 1 :(得分:1)
如果您对Django ORM比使用原始SQL更熟悉,您可以考虑使用Model - > BackupModel - > TestModel - >模型,除了最后一步之外的所有步骤都可以在不丢弃数据的情况下执行。
def backup(InModel,OutModel):
in_objs = InModel.objects.all()
for obj in in_objs:
out_obj = OutModel.convert_from(InModel,obj)
out_obj.save()
在这里,您只需确保所有模型都实现了convert_from方法。这些都应该是微不足道的转换,除了BackupModel - > TestModel。在其他情况下,除了班级之外什么都不会改变,所有数据都保持相同。
这样做的好处是,在重新编写所有界面之前,您可以使用TestModel并确保您的转换符合您的想法。如果一切都出错,您可以从BackupModel->模型转换,一切正常。在最糟糕的情况下,您放弃Django的ORM,运行回SQL,只需将所有以backupmodel __ *开头的表重命名为数据库中的__ *模型。
免责声明:我从未这样做过。
答案 2 :(得分:1)
大约有5或6个工具可以帮助自动化部分迁移。其中有几个列在this question中,为了完整起见,我将添加其他内容。
接下来,请参阅S. Lott's answer至this question about migration workflows,了解如何在模型名称中使用版本号以简化迁移,包括构建独立脚本以正确转换表格。在我看来,非常优越来序列化导出数据,然后尝试通过导入来构建新表。
最后,我还没有想到一种正确进行热迁移的方法,也没有看到任何其他地方的任何提示,因此维护停机是不可避免的。
答案 3 :(得分:1)
分步进行所有迁移!
如果您需要添加字段,请继续添加,使用默认值或可选。这很安全。 如果需要创建现有的可选字段,请先为其指定默认值。 如果需要使默认情况下的现有字段不具有默认值,请在修复创建实例的所有代码后删除默认字段。 如果需要更改字段的类型,请首先添加一个继承当前值的新字段。然后,运行脚本以更新现有实例以填充新字段。第三,删除使用旧字段的所有代码以使用新字段。最后,没有使用原始代码,你可以放弃它。
对于每种情况,您都可以迈出一小步。对于每一个更大的变化,你都可以把它分解成小的变化。这是一个迭代开发得到回报的地方。保持良好的备份,不要害怕经常推送!快速做出小改动,看看它们是否有效。