25
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsでデータコンバートを行う時は専用のスクリプトを書くと良い

Last updated at Posted at 2017-05-29

はじめに

Webサービスを作っているとサービスの成長に合わせて初期のデータ構造を変更することがあります。
そんな時に必要なのが現在のデータを新しいデータ構造に合わせるためのデータコンバートです。
そんなデータコンバートでよく利用する方法を紹介します。

今回の環境

gem 'rails', '4.2.8'

基本的にはRails5系でもデータコンバートのスクリプトは動作すると思います。

他のデータコンバートの方法

マイグレーションにデータコンバートを書く

マイグレーションファイルに書けばDBの構造変更とコンバートの関連性が分かりやすいというメリットがあります。
ただ、マイグレーションファイルに書くと再実行がやりにくいというデメリットがあります。

モデルにデータコンバートを書く

Rails的に書けるのですが、データコンバートが終了すると、ほぼ使われないコードがアプリケーション本体のコードに混ざってしまうので、徐々にFatモデルになっていくのが辛いです。
なるべくデータコンバート処理はアプリケーション本体とは分離したいですね。

SQLを書く

単純なUpdateなどシンプルなコンバートならSQLを直接かいてもよいのですが、条件によってコンバート内容を変更する場合などを考えるとRailsで書きたいところです。

データコンバート専用スクリプトを書く

それではデータコンバート用のスクリプトを書いてみます。
スクリプトは専用のフォルダを作ってそこにまとめるようにしています。
例えば script/convert_users.rb というファイルを作ります。

script/convert_users.rb
User.transaction do
  convert_count = 0
  User.all.each.with_index(1) do |user, i|
    user.nickname = 'NO NAME'
    user.save!
    convert_count = i
  end
  
  puts "User count: #{User.count}"
  puts "Convert count: #{convert_count}"
  
  print 'Are you sure?(yes/no) > '
  if gets.strip == 'yes'
    puts 'committed'
  else
    puts 'rollback'
    raise ActiveRecord::Rollback
  end
end

データコンバートはRailsで書きます。
複数データの更新であれば transaction ブロックで囲みます。

puts "User count: #{User.count}"
puts "Convert count: #{convert_count}"

puts で実行結果を出力してコンバートの整合性を確認できるようにしています。

print 'Are you sure?(yes/no) > '
if gets.strip == 'yes'
  puts 'committed'
else
  puts 'rollback'
  raise ActiveRecord::Rollback
end

またスクリプト実行時に内容を確認してからコミットできるようにメッセージを表示してコミット or ロールバックを選択できるようにしています。

データコンバート専用スクリプトを実行する

それではスクリプトを実行してみましょう。
ターミナルでRailsのアプリケーションフォルダまで移動してスクリプトを実行します。

rails runner script/convert_users.rb

実行すると下記のように結果が表示されます。
コンバート結果を確認して問題なければ yes と入力してコンバート結果をコミットします。

User count: 10
Convert count: 10
Are you sure?(yes/no) >

メリット

このようにデータコンバート専用スクリプトを書いておくと、何度でもコマンドラインから実行することが可能となります。アプリケーション本体とも分離しているので本体を汚すこともありません。
また、スクリプトはgitに含めるようにしているので、コードレビューでマイグレーションとの整合性も含めてチェックすることができます。

デメリット

例えばマイグレーションを伴うデータコンバートの場合には、マイグレーション実行 ⇒ データコンバート実行 となるのでコンバートまでに多少の時間差が発生してしまいます。
その為、作りによってはデータの不整合が発生することがあるかもしれません。

  • 一旦サービスを停止してから実施する
  • 時間差が発生しても問題ない作りにする
  • なるはやでデータコンバートを実行する!

上記の様な事を意識する必要があります。

まとめ

今回はよく使うデータコンバートの方法を紹介しました。
データコンバートの方法について「こんな方法もあるよ」などあれば教えてください。

25
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?