I'm running some bizarre Postgres migration code from OpenCongress and I'm getting this error:
RuntimeError: ERROR     C25001  MVACUUM cannot run inside a transaction block Fxact.c  L2649   RPreventTransactionChain: VACUUM FULL ANALYZE; So I'd like to try running it without getting wrapped by a transaction.
On databases that support transactions with statements that change the schema, migrations are wrapped in a transaction. If the database does not support this then when a migration fails the parts of it that succeeded will not be rolled back. You will have to rollback the changes that were made by hand.
To run a specific migration up or down, use db:migrate:up or db:migrate:down . The version number in the above commands is the numeric prefix in the migration's filename. For example, to migrate to the migration 20160515085959_add_name_to_users. rb , you would use 20160515085959 as the version number.
A Rails migration is a tool for changing an application's database schema. Instead of managing SQL scripts, you define database changes in a domain-specific language (DSL). The code is database-independent, so you can easily move your app to a new platform.
There's now a method disable_ddl_transaction! that allows this, e.g.:
class AddIndexesToTablesBasedOnUsage < ActiveRecord::Migration   disable_ddl_transaction!   def up     execute %{       CREATE INDEX CONCURRENTLY index_reservations_subscription_id ON reservations (subscription_id);     }   end   def down     execute %{DROP INDEX index_reservations_subscription_id}   end end ActiveRecord::Migration has the following private method that gets called 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 see this will wrap the migration in a transaction if the connection supports it.
In ActiveRecord::ConnectionAdapters::PostgreSQLAdapter you have:
def supports_ddl_transactions?   true end SQLite version 2.0 and beyond also support migration transactions. In ActiveRecord::ConnectionAdapters::SQLiteAdapter you have:
def supports_ddl_transactions?   sqlite_version >= '2.0.0' end So then, to skip transactions, you need to somehow circumvent this. Something like this might work, though I haven't tested 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 could then set up your migration as follows:
class SomeMigration < ActiveRecord::Migration   no_transaction    def self.up     # Do something   end    def self.down     # Do something   end end If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With