ActiveRecord::Migration
ma następującą prywatną metodę, która jest wywoływana podczas uruchamiania migracje:
def ddl_transaction(&block)
if Base.connection.supports_ddl_transactions?
Base.transaction { block.call }
else
block.call
end
end
Jak widać to będzie zawijać migrację w transakcji, jeśli połączenie obsługuje.
W ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
masz:
def supports_ddl_transactions?
true
end
SQLite w wersji 2.0, a także obsługuje transakcji poza migracji. W ActiveRecord::ConnectionAdapters::SQLiteAdapter
masz:
def supports_ddl_transactions?
sqlite_version >= '2.0.0'
end
Tak więc, aby pominąć transakcje, trzeba jakoś obejść to. Coś jak to może działać, choć nie mam go Testowany:
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
Następnie można skonfigurować migrację następująco:
class SomeMigration < ActiveRecord::Migration
no_transaction
def self.up
# Do something
end
def self.down
# Do something
end
end
Proszę powiedzieć nieco więcej o migracji, którego używasz, baza jesteś używając i który adapter na wypadek, gdyby nie był domyślnym mysql/sqlite. W ten sposób myślę, że odpowiedź na twoje pytanie będzie bardziej odpowiednia. – Ariejan
Niestety, widziałem, że używasz PostgreSQL. – Ariejan
W przypadku tej konkretnej migracji dowiedziałem się, że polecenie "VACUUM" nie jest naprawdę konieczne (służy tylko do zbierania śmieci), więc usunięcie tego połączenia zadziałało, ale wciąż jestem ciekawy, jak polecić Railsom uruchamianie migracje bez transakcji. – hsribei