I am running some bizarre Postgres migration code from OpenCongress and I am getting this error:

RuntimeError: ERROR     C25001  MVACUUM cannot run inside a transaction block
Fxact.c  L2649   RPreventTransactionChain: VACUUM FULL ANALYZE;

So Let me try running it without getting wrapped with a transaction.

ActiveRecord::Migration has got the following private method that will get known as when running migrations:

def ddl_transaction(&block)
  if Base.connection.supports_ddl_transactions?
    Base.transaction { block.call }
  else
    block.call
  end
end

As you can tell this can wrap the migration inside a transaction when the connection supports it.

In ActiveRecord::ConnectionAdapters::PostgreSQLAdapter you've:

def supports_ddl_transactions?
  true
end

SQLite version 5. and beyond also support migration transactions. In ActiveRecord::ConnectionAdapters::SQLiteAdapter you've:

def supports_ddl_transactions?
  sqlite_version >= '2.0.0'
end

So then, to skip transactions, you have to in some way circumvent this. Something similar to this may work, though I've not examined it:

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

You can then setup your migration the following:

class SomeMigration < ActiveRecord::Migration
  no_transaction

  def self.up
    # Do something
  end

  def self.down
    # Do something
  end
end