Django migrate未执行部分迁移文件,如何无损同步模型变更?
解决Django迁移不同步且无法检测变更的问题
这种情况我在维护Django项目时碰到过好几次,核心原因基本都是Django的迁移状态表(django_migrations)和本地迁移文件的记录不匹配,导致migrate命令误判迁移已应用,而重新生成迁移时又因为状态混乱检测不到变更。下面是一套安全的操作步骤,保证不丢失数据:
1. 先排查当前迁移状态
首先得把问题摸清楚:
- 运行
python manage.py showmigrations,查看目标app的迁移记录,哪些标记了[X](已应用),哪些没有。对比本地migrations文件夹里的文件,看看是否存在“数据库标记已应用但本地文件已删除/不存在”的情况。 - 直接查询Postgres数据库的迁移状态表,执行SQL:
把查询结果和本地迁移文件名对比,找出那些不一致的记录(比如数据库里有某条迁移记录,但本地已经没有对应的.py文件,或者反过来)。SELECT * FROM django_migrations WHERE app = '你的_app名称';
2. 备份数据库(重中之重)
在做任何修改之前,一定要先备份数据,避免操作失误导致数据丢失:
pg_dump -U 你的数据库用户名 数据库名称 > backup_$(date +%Y%m%d).sql
3. 修正迁移状态不匹配
如果数据库里错误标记了某些未实际执行的迁移为已应用,需要手动清理这些错误记录:
- 执行SQL删除错误的迁移记录(替换成你要删除的迁移文件名,注意不带
.py后缀):DELETE FROM django_migrations WHERE app = '你的_app名称' AND name IN ('0003_xxx', '0004_yyy'); - 清理完成后,再运行
python manage.py showmigrations,确认状态和本地文件一致。
4. 重新生成并执行迁移
现在可以重新生成正确的迁移文件了:
- 删除目标app的
migrations文件夹中除了__init__.py之外的所有文件(如果之前的迁移文件已经混乱的话)。 - 运行
python manage.py makemigrations,此时Django应该能正确检测到所有模型变更,生成新的迁移文件。 - 最后运行
python manage.py migrate,这次会正常执行所有新生成的迁移,把模型变更同步到数据库。
特殊场景处理
如果遇到复杂变更(比如字段类型修改、字段重命名):
- 字段重命名时,不要直接修改models里的字段名,应该分两步:先添加新字段,写迁移把旧字段的数据复制到新字段,再删除旧字段,分两次执行迁移,避免数据丢失。
- 如果你的模型结构已经和数据库实际结构一致,但迁移状态还是乱的,可以用
python manage.py migrate --fake来同步状态(这个命令只会标记迁移为已应用,不会执行SQL,所以一定要确认模型和数据库结构完全匹配再用)。
内容的提问来源于stack exchange,提问作者Marouan
相关产品推荐
相关产品推荐

