Django迁移在生产环境不生效问题排查与解决咨询
Django Docker部署后迁移未生效的排查与解决
问题现象
- 本地环境:修改Django模型后生成迁移文件,通过
docker-compose重建容器,数据库变更可正常应用 - 部署服务器:拉取仓库代码并重建容器后,数据库未体现迁移变更;进入PostgreSQL容器手动查看无修改,进入Django容器重新执行
migrate也无效果 - 提供的Django容器entrypoint脚本:
#!/bin/bash ### WAITING POSTGRES START ### RETRIES=7docker exec -it <your_backend_container_name> python manage.py showmigrations host="postgis" while [ "$RETRIES" -gt 0 ]; do echo "Waiting for postgres server, $((RETRIES--)) remaining attempts..." PG_STATUS="$(pg_isready -h $host -U postgres)" PG_EXIT=$(echo $?) echo "Postgres Status: $PG_EXIT - $PG_STATUS" if [ "$PG_EXIT" = "0" ]; then RETRIES=0 else sleep 5 # timeout for new loop fi done # run command from CMD python manage.py makemigrations python manage.py migrate exec "$@"
排查与解决步骤
1. 修复entrypoint脚本语法错误
脚本中RETRIES=7docker exec -it <your_backend_container_name> python manage.py showmigrations存在语法错误:变量赋值与命令未拆分,导致RETRIES值异常,后续循环逻辑失效,可能使migrate未正确执行。
修正后的脚本:
#!/bin/bash ### WAITING POSTGRES START ### RETRIES=7 # 生产环境建议移除该行,避免容器内执行外部命令的风险 # docker exec -it <your_backend_container_name> python manage.py showmigrations host="postgis" while [ "$RETRIES" -gt 0 ]; do echo "Waiting for postgres server, $((RETRIES--)) remaining attempts..." PG_STATUS="$(pg_isready -h $host -U postgres 2>&1)" PG_EXIT=$? echo "Postgres Status: $PG_EXIT - $PG_STATUS" if [ "$PG_EXIT" -eq 0 ]; then RETRIES=0 else sleep 5 fi done # 生产环境禁止自动执行makemigrations,迁移文件需提前本地生成并提交仓库 # python manage.py makemigrations python manage.py migrate exec "$@"
关键修正点:
- 拆分
RETRIES=7与后续命令,修复变量赋值错误 - 直接通过
PG_EXIT=$?获取命令退出码,无需额外echo - 为
pg_isready添加2>&1捕获错误输出,便于排查连接问题 - 注释生产环境危险的
makemigrations:迁移文件需在本地生成并提交至版本库,容器启动仅执行migrate,避免环境差异导致迁移文件不一致
2. 确认服务器迁移文件同步状态
- 进入Django容器,执行
python manage.py showmigrations,查看迁移文件的应用状态(是否存在未标记为applied的迁移) - 检查服务器拉取的代码中,对应应用的
migrations目录是否包含本地提交的最新迁移文件,若缺失需排查Git拉取分支、命令是否正确
3. 验证数据库连接与迁移记录
- 检查Django
settings.py中的数据库配置,确认部署环境连接的是目标PostgreSQL容器,而非其他数据库实例 - 进入PostgreSQL容器,执行
psql -U postgres,查询django_migrations表确认迁移记录:
SELECT * FROM django_migrations WHERE app='<你的应用名称>';
- 若已存在对应迁移记录,说明迁移曾执行但可能失败;若不存在,说明
migrate未触发或未连接到正确数据库
4. 手动执行迁移并查看日志
- 进入Django容器,执行
python manage.py migrate --verbosity 2,查看详细执行日志,排查是否存在字段冲突、权限不足等报错 - 若提示"No migrations to apply"但数据库未更新,需对比本地与服务器的迁移文件内容是否一致
5. 检查容器启动日志
- 执行
docker-compose logs <django容器名称>,查看entrypoint脚本的执行日志,确认migrate命令是否正常触发、是否有报错信息
内容的提问来源于stack exchange,提问作者Emanon24522
相关产品推荐
相关产品推荐

