← 中文资源

简体中文版本

Rails ActiveRecord::PendingMigrationError — 迁移未执行

通过执行待处理迁移、理解 db:prepare,并在部署前解决迁移冲突,修复 PendingMigrationError。

阅读英文原文

症状

错误“Rails ActiveRecord::PendingMigrationError — 迁移未执行”指向一个明确的失效模式。下面依次给出症状、定位该原因的检查命令、根本原因、修复方案,以及证明修复有效的验证步骤。

可观察到的症状包括:

  • Rails 对任何请求抛 ActiveRecord::PendingMigrationError
  • 本地可启动,预发环境报错
  • 新增了迁移文件却从未应用

诊断

先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。

步骤 1

bin/rails db:migrate:status

列表会以 “down” 标出待处理迁移,明确指出需运行哪些。

步骤 2

bin/rails db:migrate

运行迁移会更新 schema_migrations 并清除待处理状态。

常见诱因(按出现频率排序):

  • 新迁移已提交但在当前环境未运行
  • 数据库被重置或从早于迁移的备份恢复
  • 两个分支添加了时间戳相同的迁移

根因

Rails 会检查每个迁移文件是否在 schema_migrations 中有对应记录。若有未应用者,会以 PendingMigrationError 拒绝请求,以免在不符预期的结构上运行。

修复

在受影响环境运行 bin/rails db:migrate,在部署脚本用 bin/rails db:prepare 幂等地创建或迁移,并通过 rails g migration 生成以避免重复时间戳。

注意:在生产运行 db:reset 或 db:drop 会销毁数据;只能使用 db:migrate 或 db:prepare。

# inspect and apply
bin/rails db:migrate:status
bin/rails db:migrate

# deploy hook: idempotent create-or-migrate
bin/rails db:prepare

# generate a migration with a unique timestamp
bin/rails generate migration AddStatusToOrders status:string

验证

重新加载应用并确认请求成功;检查 db:migrate:status 显示全部迁移为 up。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。