我正在编写一个 Rspec 测试来测试使用 Rails ActiveRecord 为 postgres 数据库进行的新迁移。迁移文件同时添加了索引,所以我的迁移包括:
disable_ddl_transaction!
add_index :table_name, [:column_1, :column_2], algorithm: :concurrently
运行迁移或回滚没有问题。但是当我编写规范文件时,我需要恢复到以前的迁移,其中包括删除索引,并且我遇到了此错误:
ActiveRecord::StatementInvalid:
PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block
: SELECT pg_advisory_unlock(7815322980726126075)
# ./spec/migrations/<FILE_NAME>.rb:17:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# PG::ActiveSqlTransaction:
# ERROR: DROP INDEX CONCURRENTLY cannot run inside a transaction block
试图理解为什么我能够在开发中回滚迁移,但在我的测试环境中遇到此 postgres 错误。
rails-rspec
有一个默认配置,导致它在自己的数据库事务中运行每个示例,通常在一个示例之后回滚,以便数据库再次为下一个示例保持干净。
您可以在 rspec-rails 中全局禁用这些事务:
RSpec.configure do |c|
c.use_transactional_examples = false
end
但是,您必须手动确保在每个测试中执行的更改不会影响其他测试的现有数据库,例如通过在
after
块中运行清理或/使用诸如 database-cleaner
gem 之类的东西。
请参阅文档了解详细信息和示例。