回滚到指定迁移版本用 python manage.py migrate app_name migration_name,django 自动判断正向或反向执行;需先用 showmigrations 确认状态,生产环境禁止直接回滚,应使用备份 sql 手动操作。

回滚到指定迁移版本用 python manage.py migrate
直接执行 python manage.py migrate app_name migration_name 就能回退到目标迁移文件(不含该文件),或前进到它(含该文件)。比如当前在 0005_add_status,想退回上一版,运行 python manage.py migrate myapp 0004_alter_user_email 即可。Django 会自动计算正向/反向路径,不需要手动指定方向。
常见错误是输错迁移名——Django 不报错,但实际没变化。建议先用 python manage.py showmigrations myapp 确认已应用的迁移列表,带 [X] 的才是已执行的。
彻底清空迁移记录并重置数据库用 python manage.py migrate --fake-initial
当本地开发中删了迁移文件、改了 models.py 又不想丢数据时,容易误用 --fake 导致后续迁移失败。正确做法是:先删掉数据库里所有 django_migrations 表中对应 app 的记录,再删本地迁移文件(保留 __init__.py),运行 python manage.py makemigrations 生成新初始迁移,最后加 --fake-initial 告诉 Django “这张表已存在,别真建”。
注意:--fake-initial 只对检测为“初始迁移”的文件生效;如果模型字段和数据库实际结构不一致,它不会校验,后续 migrate 可能报错。
回滚失败后手动修复 django_migrations 表
当迁移抛出 OperationalError: no such column 或 IntegrityError 卡住时,Django 已写入 django_migrations 但数据库变更未完成,状态不一致。此时不能直接重跑 migrate。
安全做法是:
- 进数据库查
SELECT * FROM django_migrations WHERE app = 'myapp' ORDER BY applied DESC LIMIT 3; - 确认最后一条记录是否对应刚失败的迁移名
- 若已写入但 DB 没变,用
DELETE FROM django_migrations WHERE app = 'myapp' AND name = '0006_drop_old_field';回退记录 - 再检查对应表结构,手动补列或删列(用
ALTER TABLE),确保与模型一致
跳过这步强行 --fake,下次迁移大概率因结构不匹配中断。
生产环境禁止用 migrate 回滚,必须走 SQL 备份+脚本
线上数据库一旦有真实数据,python manage.py migrate app_name prev_migration 可能触发不可逆的 DROP COLUMN 或数据截断。Django 的反向迁移只保证“结构可逆”,不保证“数据可逆”。
真正安全的做法是:
- 每次上线前导出当前结构快照:
python manage.py sqlmigrate myapp 0005 > backup_0005.sql - 人工审查生成的 SQL,确认无
DROP、RENAME等高危操作 - 回滚时不用 Django 命令,而是用备份 SQL + 手动编写回退 SQL(如用
ADD COLUMN补字段)
很多团队踩坑在于把开发流程直接搬上生产——Django 迁移不是部署工具,它是开发辅助机制,数据安全边界得靠人盯。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











