You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已完成迁移仍检测到重复迁移,Django预生产部署失败

问题原因

你遇到的问题根源有两个:

  1. 部署时自动生成迁移+删除数据库卷:每次部署执行docker-compose down -v会彻底删除PostgreSQL的数据卷,导致数据库里的迁移历史表(django_migrations)被清空。而你的entrypoint脚本每次启动都跑makemigrations --noinput,Django会对比当前模型和空数据库,重新生成和上月完全一样的迁移文件。
  2. 重复迁移执行冲突:当你再次执行migrate时,新生成的迁移会尝试删除已经在上月删除的字段,自然报错。

解决方案

1. 修正部署流程,保留数据库迁移历史

把部署步骤里的down -v改成down(去掉-v参数):

sudo docker-compose -f docker-compose.preprod.yml down
git pull
sudo docker-compose -f docker-compose.preprod.yml up -d --build --remove-orphans
sudo docker-compose -f docker-compose.preprod.yml up

-v会删除挂载的卷,包括PostgreSQL的数据存储,这会丢失所有数据库数据和迁移记录,预生产环境绝对不能这么操作。

2. 修改entrypoint.sh,禁止部署时自动生成迁移

迁移文件应该在本地开发完成后,手动生成并提交到Git仓库,部署时只需要执行migrate即可。把entrypoint里的python manage.py makemigrations --noinput删掉:

#!/bin/sh

if [ "$DATABASE" = "postgres" ]
then
    echo "Waiting for postgres..."

    while ! nc -z $SQL_HOST $SQL_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

python manage.py migrate

exec "$@"

3. 修复当前预生产环境的错误状态

如果现在预生产数据库已经因为down -v被清空,或者迁移状态混乱,可以按以下步骤修复:

  • 先确保本地仓库里有上月生成的正确迁移文件(就是之前已经应用过的那些)
  • 启动容器后,进入Django容器:
sudo docker-compose -f docker-compose.preprod.yml exec web bash
  • 标记所有已存在的迁移为已应用(避免重复执行):
python manage.py migrate --fake
  • 如果数据库是空的,也可以直接重新应用所有迁移(适合数据可以重新导入的情况):
python manage.py migrate

额外建议

  • 预生产环境的数据库数据和迁移记录必须持久化,永远不要用down -v除非你明确要彻底清空环境。
  • 迁移文件属于代码的一部分,必须和模型修改一起提交到Git,部署时只执行migrate,不要在服务器上生成迁移。

内容的提问来源于stack exchange,提问作者Mereva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 19:50:47