Alstrocrack Tech Blog

考えたこと、学んだこと など

data-migrate gemの使い方

はじめに

Ruby on Rails でのアプリケーション開発を行う際にrails db:migrateコマンドを実行して、RDB の schema 変更を行うことがあると思います。

これと同じように RDB 内に作成するデータそのものを migration 操作できる gem が存在します。

github.com

RDB 内でのマスターデータの操作には、手動で SQL を実行したり rake などを書いたりすることもあるでしょう。私が現在所属している開発チームでは、RDB 内のマスターデータの管理などにはこの data-migrate gem を利用しており、私もこの gem でのデータ操作に慣れてしまいました。

今回は自分への備忘録も兼ねて、この data-migrate gem の基本的な使い方を記載しておこうと思います。

と言っても、使い方は実は Rails オリジナルの db:migrate 系のコマンドのdbdataにするだけです。

Installation

Gemfile への追加は以下です。もちろん、Gemfile への追加後にbundle installを実行します。

# Gemfile

gem 'data_migrate'

# "Support Rails 6.1 through 8.0"
# "For Rails 6.0 support, please use gem version 9.1.x:"
# READMEに上記のように記載があるので、古いバージョンのRailsを使っている場合には、それに応じたgemのバージョンを指定しないといけない

gem 'data_migrate', '~> 9.1.0'

How to use

新しい migration を実行

新しい migration を実行する場合の手順は以下です。これは db:migrate 系と全く同じです。

  1. data_migrationファイルの生成
  2. data_migrateコマンドによる migration の実行

以下で実際に実行してみます。

# ちなみにschema変更の際には以下のコマンド
# $ rails g migration AddPartNumberToProducts

# 新しいdata migrationファイルを追加
$ rails g data_migration add_this_to_that
      create  db/data/20260124062455_add_this_to_that.rb

出力にあるように、新しい migration ファイルがdb/data以下に作成されています。 ファイルの中身は以下の通りです。

# db/data/20260124062455_add_this_to_that.rb

# frozen_string_literal: true

class AddThisToThat < ActiveRecord::Migration[7.2]
  def up
  end

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

migration ファイルに、操作したい内容を up と down に記述します。例えば、こんな感じです。

# frozen_string_literal: true

class AddThisToThat < ActiveRecord::Migration[7.2]
  def up
    Item.create!(id: 1, name: 'test')
  end

  def down
    Item.find(1).destroy!
  end
end

そして、db:migrate 系と同様にdata:migrateコマンドを実行します。

$ rails data:migrate
== 20260124062455 AddThisToThat: migrating ====================================
== 20260124062455 AddThisToThat: migrated (0.0546s) ===========================

これで RDB に新しいデータを追加することができました。

migration のステータス確認

これも$ rails db:migrate:statusとほとんど同じです。status に応じて up か down かが記載されているはずです。

$ rails data:migrate:status

database: db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20260124062455  Add this to that

migration のバージョンを巻き戻す

migration を 1 バージョン分、巻き戻したい場合はこちら。

$ rails data:rollback
== 20260124062455 AddThisToThat: reverting ====================================
== 20260124062455 AddThisToThat: reverted (0.0303s) ===========================

特定のバージョンを巻き戻したい場合は以下のどちらかを実行します。

$ rails data:rollback VERSION=20260124062455
== 20260124062455 AddThisToThat: reverting ====================================
== 20260124062455 AddThisToThat: reverted (0.0137s) ===========================
$ rails data:migrate:down VERSION=20260124062455
== 20260124062455 AddThisToThat: reverting ====================================
== 20260124062455 AddThisToThat: reverted (0.0267s) ===========================

使い方がわからなくなった場合

ヘルプの確認は以下のコマンドから。

$ rails -T data
bin/rails data:abort_if_pending_migrations          # Raises an error if there are pending data migrations
....

よく使うコマンドのセット

# migrationの追加
$ rails g data_migration add_this_to_that

# migrationの実行
$ rails data:migrate

# migrationのステータス確認
$ rails data:migrate:status

# migrationの巻き戻し
# 前のバージョンへ巻き戻す
$ rails data:rollback

# 特定のバージョンを巻き戻す
$ rails data:rollback VERSION=20260124062455
$ rails data:migrate:down VERSION=20260124062455

まとめ

繰り返しですが、基本的に db:migrate 系コマンドのdbdataに置き換えるだけです。このことからも分かるように、できることも db:migrate 系と同様です。