ruby-on-rails – 如何在Rails中启动事务的情况下运行迁移?

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 如何在Rails中启动事务的情况下运行迁移?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我从 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

猜你在找的Ruby相关文章