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

升级至Rails 6.1后运行RSpec时schema_migrations表条目丢失引发测试失败问题排查

Rails 6.1 + RSpec + Oracle: schema_migrations 条目丢失导致测试失败

看起来你在升级到Rails 6.1后,被测试环境里的数据库迁移问题折腾得不轻——尤其是schema_migrations表条目莫名丢失,一会儿提示环境信息找不到,一会儿又说迁移未完成。结合你的配置和Oracle数据库的特性,我来帮你拆解问题并给出解决方案:

核心问题定位

首先得揪出你配置里的一个关键笔误:在DatabaseCleaner.clean_with的参数里,你写的是expect: %w(ar_internal_metadata schema_migrations),但正确的参数名应该是except!这个错误直接导致DatabaseCleaner忽略了你的排除表配置,每次执行清理时都会截断所有表,包括schema_migrations和ar_internal_metadata——这就是为什么你设置完环境后,一跑测试就只剩一条迁移记录的原因。

另外,Rails 6.1新增了ar_internal_metadata表来跟踪数据库环境,Oracle默认把表名转成大写存储(你日志里的SCHEMA_MIGRATIONS就是明证),这和Rails默认的小写表名规则冲突,也会加剧这个问题。

分步解决方案

1. 修复DatabaseCleaner的配置错误

立刻修正rails_helper.rb里的笔误,把expect改成except:

config.before(:suite) do
  DatabaseCleaner.clean_with :truncation, except: %w(ar_internal_metadata schema_migrations)
  DatabaseCleaner.strategy = :transaction
end

这个修改会告诉DatabaseCleaner在执行全表截断时,跳过这两个核心系统表,避免迁移记录和环境信息被误删。

2. 适配Oracle的表名大小写规则

Oracle默认将表名存储为大写,而Rails ActiveRecord默认用小写。为了避免表名不匹配的问题,你可以在config/environments/test.rb里添加以下配置:

config.active_record.table_name_prefix = ''
config.active_record.table_name_suffix = ''
# 让Rails生成大写的表名
config.active_record.default_table_name = lambda { |klass|
  klass.model_name.plural.upcase
}

这样Rails在创建表时会自动使用大写名称,和Oracle的规则对齐,避免查询时找不到表的问题。

3. 彻底重置测试数据库

执行以下命令,完全重建测试环境的数据库,确保所有系统表和迁移记录都正确初始化:

# 删除测试数据库
bin/rails db:drop RAILS_ENV=test
# 创建新的测试数据库
bin/rails db:create RAILS_ENV=test
# 执行所有迁移
bin/rails db:migrate RAILS_ENV=test
# 设置测试环境标记
bin/rails db:environment:set RAILS_ENV=test

4. 优化DatabaseCleaner的策略(可选)

对于Oracle数据库,事务策略在某些场景下(比如JS驱动的特性测试)可能会有问题。如果后续测试仍有异常,可以按测试类型调整清理策略:

config.before(:each) do
  # 对于需要跨连接的测试(如JS测试),用截断策略
  if example.metadata[:js] || example.metadata[:type] == :feature
    DatabaseCleaner.strategy = :truncation, except: %w(ar_internal_metadata schema_migrations)
  else
    # 其他测试用事务策略,更快更安全
    DatabaseCleaner.strategy = :transaction
  end
end

额外检查项

  • 确认你的迁移文件里没有手动操作schema_migrations表的代码,这会干扰Rails的迁移跟踪机制。
  • 保持activerecord-oracle_enhanced-adapter版本和Rails版本兼容(你当前用的6.1.4是适配Rails 6.1的,没问题)。
  • 如果schema.rb不能很好地兼容Oracle特性,可以切换到structure.sql:执行bin/rails db:structure:dump RAILS_ENV=test,然后删除schema.rb,Rails会自动使用structure.sql来管理数据库结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 20:57:51