RailsのDBをMySQLからsqliteに移行する

異なるDBのデータ移行はめっちゃ面倒な印象があったけど、やってみたらそこまででもなかったぞという話をメモしておきます。

前提

MySQL特有のクエリを書いていない

データ移行手順

rroblak/seed_dump: Rails task to dump your data to db/seeds.rb を利用する。このgemを使うとrake db:seed:dumpでdb/seeds.rb にDBの内容をダンプできる。ダンプした内容を移行先に持ち込んで、おもむろにbin/rails db:seedするとデータの移行ができる。便利。

ただしrake db:seed:dumpだとREADMEに書いてあるようにモデルのcreate!メソッドの実行になるし、idが指定されない形になってしまう。

Product.create!([
  { category_id: 1, description: "Long Sleeve Shirt", name: "Long Sleeve Shirt" },
  { category_id: 3, description: "Plain White Tee Shirt", name: "Plain T-Shirt" }
])
User.create!([
  { password: "123456", username: "test_1" },
  { password: "234567", username: "test_2" }
])

これだと移行後に外部キーがマッチしない可能性がある。あと各モデルのコールバックが不用意に発火する可能性がある。

INSERT_ALL=true INCLUDE_ALL=true RAILS_ENV=production bundle exec rake db:seed:dumpのようにしてダンプするとこの問題を解決できる。

INSERT_ALL=trueとするとRails6から利用可能なinsert_allを使う形式になりコールバックをスキップできる(あと速い)。INCLUDE_ALL=trueとするとidやcreated_at, updated_atも含んだ形でダンプできる。

細かい振る舞いは公式のドキュメント読んでください。