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

Django应用部署到Heroku后迁移循环异常致崩溃求助

问题分析与解决:Heroku上Django迁移重复生成且状态矛盾的问题

问题现象

  • 本地代码与Heroku仓库已同步,本地执行makemigrations或migrate时无变更提示
  • Heroku上执行makemigrations users kits email,会重复生成完全相同的迁移文件,内容为修改historicalkit/historicaluser的Meta选项和history_date字段:
    python manage.py makemigrations users kits email
    Migrations for 'kits':
      apps/kits/migrations/0002_auto_20221209_1204.py
        - Change Meta options on historicalkit
        - Alter field history_date on historicalkit
    Migrations for 'users':
      apps/users/migrations/0002_auto_20221209_1204.py
        - Change Meta options on historicaluser
        - Alter field history_date on historicaluser
    
  • Heroku执行migrate时,系统同时出现矛盾提示:既显示无迁移可应用,又提示**'kits'、'users'应用存在未反映到迁移中的变更**,最终导致Web应用崩溃:
    python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, email, kits, sessions, users
    Running migrations:
      No migrations to apply.
      Your models in app(s): 'kits', 'users' have changes that are not yet reflected in a migration, and so won't be applied.
      Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
    

核心原因

这类问题几乎都和django-simple-history(自动生成historical*模型的第三方库)的环境差异或迁移状态不匹配有关:

  1. 环境配置不一致:本地与Heroku的时区设置、django-simple-history版本不同,导致自动生成的历史模型字段(如history_date的时区属性)或Meta选项存在隐性差异,Django每次检测都认为需要修改。
  2. 迁移状态哈希冲突:Heroku数据库的django_migrations表中,已记录该迁移为已应用,但迁移文件的哈希值(Django判断迁移是否生效的标识)与本地不一致,导致系统陷入"已应用但仍有变更"的循环。
  3. 数据库表结构隐性差异:Heroku数据库中historicalkit/historicaluser表的实际字段结构,与本地模型生成的预期结构存在差异,Django无法通过常规迁移修复,只能重复生成无效迁移。

解决步骤

1. 统一环境配置

  • 确保本地和Heroku的settings.py时区完全一致,例如都设置为:
    TIME_ZONE = 'UTC'
    
  • 检查django-simple-history版本,本地与Heroku需完全相同,在requirements.txt中固定版本号,避免自动升级导致逻辑差异。

2. 修复迁移状态不匹配

  • 先在Heroku上查看django_migrations表的状态,确认目标迁移是否已被标记为应用:
    heroku run python manage.py shell
    
    进入shell后执行:
    from django.db import connections
    cursor = connections['default'].cursor()
    cursor.execute("SELECT app, name FROM django_migrations WHERE app IN ('kits', 'users');")
    print(cursor.fetchall())
    
  • 如果查询结果显示0002_auto_20221209_1204已存在,手动标记该迁移为已应用(仅修改状态,不执行SQL):
    heroku run python manage.py migrate --fake kits 0002_auto_20221209_1204
    heroku run python manage.py migrate --fake users 0002_auto_20221209_1204
    

3. 清除重复迁移文件

  • 本地删除重复生成的迁移文件,提交到仓库后重新部署到Heroku:
    rm apps/kits/migrations/0002_auto_20221209_1204.py
    rm apps/users/migrations/0002_auto_20221209_1204.py
    git add .
    git commit -m "Remove duplicate migration files"
    git push heroku main
    

4. 校验数据库表结构

  • 登录Heroku数据库,查看historicalkit和historicaluser的实际字段结构,与本地数据库对比:
    heroku pg:psql
    # 进入psql后执行
    \d historicalkit;
    \d historicaluser;
    
  • 如果字段类型(如history_date是否带时区)与本地不一致,手动调整数据库字段,或重新生成一次合规的迁移来统一结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 13:15:30