迁移跑到一半失败了,库里是什么状态?下一次 migrate 会怎样?这篇故意写一个「先成功、后失败」的迁移,分别在 atomic 与非 atomic 下跑,再演示两种恢复办法。
migrate 结果最后一行: django.db.utils.ProgrammingError: syntax error at or near "THIS" c1 列存在: 0 django_migrations 有记录: 0
PostgreSQL、SQLite 支持事务性 DDL,所以整个迁移是一个事务。MySQL 不支持(DDL 会隐式提交),那里失败就是半应用状态(本文没有测)。
migrate 结果最后一行: django.db.utils.ProgrammingError: syntax error at or near "THIS" c1 列存在: 1 django_migrations 有记录: 0 ← 库处于「半应用」状态 再跑一次 migrate(第一条操作重复执行): django.db.utils.ProgrammingError: column "c1" of relation "lab_p" already exists
需要它的场景:CREATE INDEX CONCURRENTLY、大数据回填分批提交。代价就是失败后自己收拾。写非 atomic 迁移时,建议每个迁移只放一个操作,失败后现场容易判断。
手工撤销第一条(DROP COLUMN c1)后 c1 存在: 0 修好迁移文件之后 migrate: ['Applying lab.0002_fail... OK'] 记录: 1
手工撤销已执行的部分,让迁移可以「从头再来」;或者把剩下的部分手工做完再 --fake。
migrate lab 0001 --fake: ['Unapplying lab.0002_fail... FAKED'] c1 列仍存在: 1 记录: 0
--fake 只改记录。用之前要确认库里的实际状态确实与你要标记的迁移一致。