ValueError: Could not find common ancestor of ['0004_deadstockstathistorymodel', '0026_remove_orderdetailmodel_order_no']
说明 Django 当前在 尝试生成迁移或者执行迁移 时,发现你的迁移历史“断裂”了:
你这个 App 的迁移历史有两个分支,编号差异巨大 (0004 vs 0026),并且 Django 找不到一个共同祖先。
✅ 根本原因
你的迁移目录里可能有两个完全不同历史的迁移链,比如你:
手动添加或恢复过旧迁移文件;
或从他人那里 pull 了部分迁移但没补全中间的迁移;
或在 reset 后用旧迁移号又创建了新的迁移。
✅ 保留数据,解决断裂的推荐方案(安全可靠)
我们现在要彻底重建迁移状态,但不删除数据库数据。
🔧 步骤如下:
✅ 步骤 1:备份当前迁移文件(可选但推荐)
cp -r your_app/migrations/ your_app/migrations_backup/
如果在 PowerShell 中使用 cp -r core/migrations/ core/migrations_backup/ 命令时,目标目录 core/migrations_backup/migrations 已经存在,因此 cp 无法覆盖它。
可以先删除目标目录后再复制
Remove-Item -Recurse -Force your_app/migrations_backup/migrations
cp -r core/migrations/ core/migrations_backup/
还可以使用 -Force 强制覆盖(但不适用于已存在的目录结构)
PowerShell 的 Copy-Item 的 -Force 参数不会递归覆盖目录,所以这种方式不够健壮,仅适用于单层文件覆盖:
Copy-Item -Recurse -Force core/migrations/ your_app/migrations_backup/
✅ 步骤 2:删除所有迁移文件(保留 init.py)
find your_app/migrations -name "*.py" ! -name "__init__.py" -delete
find your_app/migrations -name “*.py” ! -name “init.py” -delete
FIND: 参数格式不正确
Get-ChildItem -Path your_app\migrations\*.py -Recurse | Where-Object { $_.Name -ne '__init__.py' } | Remove-Item -Force
✅ 步骤 3:清除数据库中记录的迁移历史(保留数据)
在数据库中执行以下 SQL:
DELETE FROM django_migrations WHERE app = 'your_app';
⚠️ 将 ‘your_app’ 替换为你出错的 app 名,例如 orders、product 等。
✅ 步骤 4:重新生成迁移(Django 会以当前模型为基础生成一个新初始迁移)
python manage.py makemigrations your_app
这会创建一个比如 0001_initial.py 的迁移文件。
✅ 步骤 5:伪造执行迁移(保留数据库结构和数据)
python manage.py migrate your_app --fake-initial
✅ 最终结果
数据完整保留
迁移状态已重建
分支断裂问题消除