我从
OpenCongress运行一些奇怪的Postgres迁移代码,我收到这个错误:
RuntimeError: ERROR C25001 MVACUUM cannot run inside a transaction block Fxact.c L2649 RPreventTransactionChain: VACUUM FULL ANALYZE;
所以我想尝试运行它,而不会被交易包裹.
解决方法
ActiveRecord :: Migration有以下私有方法,在运行迁移时被调用:
def ddl_transaction(&block) if Base.connection.supports_ddl_transactions? Base.transaction { block.call } else block.call end end
正如你可以看到的,如果连接支持它,它会将迁移包装在一个事务中.
在ActiveRecord :: ConnectionAdapters :: PostgresqlAdapter你有:
def supports_ddl_transactions? true end
sqlite 2.0及更高版本也支持迁移事务.
在ActiveRecord :: ConnectionAdapters :: sqliteAdapter你有:
def supports_ddl_transactions? sqlite_version >= '2.0.0' end
那么,为了跳过交易,你需要以某种方式规避这一点.
这样的事情可能会起作用,虽然我还没有测试过:
class ActiveRecord::Migration class << self def no_transaction @no_transaction = true end def no_transaction? @no_transaction == true end end private def ddl_transaction(&block) if Base.connection.supports_ddl_transactions? && !self.class.no_transaction? Base.transaction { block.call } else block.call end end end
然后,您可以按如下方式设置迁移:
class SomeMigration < ActiveRecord::Migration no_transaction def self.up # Do something end def self.down # Do something end end