2012-03-08 5 views
9

運用データベースにインデックスを追加します。幸いにも私たちはPostgresを実行しています。これは同時に並行してインデックスを作成できるため、ダウンタイムなしでインデックスを追加できます。キャッチ・コンカレント・インデックスはトランザクション内からは追加できません。また、レール・マイグレーションはトランザクション内のすべてをラップします。Rails 3.1の移行をトランザクション内で実行しないようにする方法はありますか?

幸運なことに、実際には単純なソリューションのように見えるものがあります。ActiveRecord :: Migrationプライベートメソッドddl_transactionをexplained hereとして上書きします。

class IndexUsersEmails < ActiveRecord::Migration 
    def ddl_transaction(&block) 
    block.call # do not start a transaction 
    end 

    def self.up 
    execute "CREATE INDEX CONCURRENTLY index_users_on_email ON users(email)" 
    end 
end 

問題は、Rails 3.1では機能しないように見えます。私はGistのコードがしていることを正確に行い、レールはそれを完全に無視するように見えます。これとどこに行くべきかについてのアイデアはありますか?

+0

は、あなたはそれがクラスメソッドだように、メソッドの定義を変更しようとしたことがありますか?例えば'def self.ddl_transaction(&block)...' –

答えて

11

ここで私は決して答えを受け入れなかったことに気付きました。だから、私がしたことを言うべきです。あなたはこのような取引から抜け出すことができ判明:

class AddFbPageIdIndexToTabs < ActiveRecord::Migration 
    def up 
    execute "END" 
    execute "CREATE INDEX CONCURRENTLY bob_lob_law_index ON bob_lob (law)" 
    execute "BEGIN" 
    end 

    def down 
    execute "END" 
    execute "DROP INDEX CONCURRENTLY bob_lob_law_index" 
    execute "BEGIN" 
    end 
end 

はちょうどあなたがトランザクション外で実行したい事前execute "END"を実行します。これにより、移行のためにActiveRecord :: Migrationが自動的に設定されたトランザクションが終了します。トランザクション外で実行したいコードが完了したら、execute "BEGIN"は新しいトランザクションを開き、ActiveRecord :: Migrationがそのクリーンアッププロセスを経て、オープンしたと考えられるトランザクションを閉じることができるようにします。

は(私はこのトリックを見つけたオンライン忘れて、今それを見つけることができません。編集はこれを調達するために歓迎!)

1

私はこれを「正しい方法」とは言っていませんが、私にとっては、1つのマイグレーションを単独で実行することでした。 20120801151807は、CREATE INDEX CONCURRENTLY移行のタイムスタンプである

rake db:migrate:up VERSION=20120801151807 

明らかに、単一の移行を実行するとトランザクションは使用されません。

関連する問題