「change_table」で「bulk: true」を使用したマイグレーションの高速化(Rails)

f:id:ryoutaku_jo:20190830001005p:plain

【結論】

Railsマイグレーションで使用されるchange_tableメソッドには、bulk: trueのオプションを設定できる

・このオプションにより、ALTER TABLEクエリにまとめてくれる

・このオプションは MySQLPostgreSQLのみサポートされていている

【目次】

【本題】

change_tableメソッドのオプション:bulk

change_tableメソッドは既存のテーブルを変更する際に使用され、create_tableメソッドと同じ要領で利用できます。

change_table :products do |t|
  t.remove :description, :name
  t.string :part_number
  t.index :part_number
  t.rename :upccode, :upc_code
end

:bulkオプション

change_tableメソッドは、bulk: trueというオプションを設定できます。

これによりALTER TABLEクエリにまとめることができます。

例えば、以下の様なマイグレーションを実行するとします。

class ChangeColumnToPosts < ActiveRecord::Migration[5.2]
  def change
    change_table :posts do |t|
      t.column :column1, :string
      t.column :column2, :string
      t.column :column3, :string
      t.column :column4, :string
      t.column :column5, :string
    end
  end
end

以下がその実行結果です。

== 20190829160054 ChangeColumnToPosts: migrating ==============================
-- change_table(:posts)
   -> 0.6061s
== 20190829160054 ChangeColumnToPosts: migrated (0.6062s) =====================

これに:bulkオプションを設定します。

class ChangeColumnToPosts < ActiveRecord::Migration[5.2]
  def change
    change_table :posts, bulk: true do |t|
      t.column :column1, :string
      t.column :column2, :string
      t.column :column3, :string
      t.column :column4, :string
      t.column :column5, :string
    end
  end
end
== 20190829160054 ChangeColumnToPosts: migrating ==============================
-- change_table(:posts, {:bulk=>true})
   -> 0.1273s
== 20190829160054 ChangeColumnToPosts: migrated (0.1274s) =====================

この様に、マイグレーションを高速化することが可能です。

なお、サポートされているのは、MySQLPostgreSQLのみとなっています。

参考情報

change_table (ActiveRecord::ConnectionAdapters::SchemaStatements) - APIdock

Class: RuboCop::Cop::Rails::BulkChangeTable — Documentation for rubocop (0.61.1)

https://aaronlasseigne.com/2012/06/05/faster-activerecord-migrations-using-change-table-bulk/

《今日の学習進捗(3年以内に10000時間に向けて)》

・テストケースの作成
手動テストの実施に向けて、テストケースの作成を進めている。
前回の手動テストで感じたことだが、手動テストにおいては、事前のテストケースを細かく洗い出しておくのは費用対効果が悪いのではないかと考えている。

テストケースとして想定できる内容であれば、コードレビュー時に概ねチェック済みであるのと、
しっかりと定義できる操作であれば、自動テストに寄せた方が良いことから、その様に考えている。
実際、前回の手動テストでは、かなりの時間を割いてテストケースを作成したが、検出出来たバグは僅かで、あまり効果的とは言えなかった。

なので、手動テストはモンキーテストを主体に、様々な操作を試みた方が効果的だと考え、今回はその方向性でテストの段取りを検討している。

しかし、モンキーテストだと担当者のスキルによって、バグが検出できる確率に偏りが出る可能性がある。
ある程度、テストの範囲を絞るなど、属人性を排した効果的な手動テストの進め方を模索して行きたい。

学習開始からの期間 :265日
今日までの合計時間:2503h
一日あたりの平均学習時間:9.5h
今日までに到達すべき目標時間:2420h
目標との解離:83h
「10,000時間」まで、

残り・・・「7497時間!」