Django初始数据填充方案及不可逆数据迁移回滚问题咨询
不可逆数据迁移的回滚方法
根据迁移所处的阶段选对应处理方式,不要硬改已经执行过的迁移文件:
- 仅本地存在、未推送到共享代码仓库的迁移
先备份城市表的现有业务数据,直接连接项目数据库做两步操作:- 打开
django_migrations表,执行DELETE FROM django_migrations WHERE name LIKE '%populate_cities%'删除对应迁移的执行记录 - 清空本次迁移错误插入的城市数据,要是迁移同时改动了表结构,同步把表结构还原到迁移执行前的状态
操作完成后就可以修改迁移文件,重新执行python manage.py migrate应用新的迁移逻辑。
- 打开
- 已推送到共享仓库、但未上线生产环境的迁移
先通知所有拉取过该版本代码的开发人员,按照上面的本地操作步骤清理各自本地开发环境的迁移记录和脏数据,之后你修正迁移文件重新提交,所有人拉取新代码后重新执行迁移即可。 - 已经上线生产环境的迁移
绝对不要回滚历史迁移,直接新建一个修复用的迁移文件:如果是之前填充的城市数据有误,就在新迁移里写逻辑删除错误数据、补入正确内容;如果是填充逻辑本身有问题,直接在新迁移里写对应的修复逻辑,上线时执行新迁移完成修正即可。
核心原则:所有已经在任何环境执行过的迁移文件,都不能直接修改,否则会导致所有环境的迁移记录和本地文件不匹配,整个迁移链路直接断裂,后续的表结构变更都会出问题。
初始数据填充的更优实现方案
不推荐把固定初始数据的填充逻辑写在迁移里,根据数据特性选对应方案即可:
- 无业务逻辑的固定基准数据(比如全国行政区划、城市列表、系统固定枚举值这类极少变动的数据)
优先用Django自带的fixtures机制:把城市数据整理成json/yaml格式的fixture文件,放在对应app的fixtures目录下,部署上线时执行python manage.py loaddata <fixture文件名>就能一键导入。这种方式数据和逻辑分离,不需要写额外Python代码,导入导出都很方便,后续如果要更新初始数据,直接替换fixture文件、补一个对应的数据更新迁移就行。 - 带业务判断逻辑的初始数据填充
实现自定义Django管理命令:在对应app的management/commands目录下新建自定义命令,比如命名为populate_cities,把数据校验、去重、填充的逻辑都写在命令里,部署时手动执行python manage.py populate_cities完成填充。这种方案完全和迁移链路解耦,就算执行出错可以直接修改命令代码重复跑,不会出现不可逆的问题,后续要做增量更新、数据修复也可以直接扩展命令参数,灵活性远高于写在迁移里。 - 确需在迁移中做数据填充的场景
用RunPython编写迁移逻辑时必须同时实现正向、反向两个函数,反向函数里明确写清楚回滚时要删除哪些数据、还原哪些字段,不要留空的回滚函数占位,从根源上避免不可逆迁移的问题。
内容的提问来源于stack exchange,提问作者famer
相关产品推荐
相关产品推荐

