csvファイルからSQLite3のRailsのseed.rbにデータを入れたい
環境
Ruby on Rails 4.2.0
ruby 2.2.0p0
背景
データベースをSQLite3にしてRailsでアプリをいじってたらぶつかったのでメモ。
データベースに入れる初期データをcsvファイルから流し込みたいってこと、ありますよね。MySQLだと load data in file~で読み込めるんですが、SQLite3だとこれが使えないっぽい。代わりに.importというのでcsvを読み込めるんですが、どうもこれが使いにくい。
.importだとcsvの列の数をテーブルのカラムの数と揃えないといけないっぽい(違ってたらごめんなさい)。ところでRailsでモデルをrails generate model~でテーブルを自動生成するとidとcreated_at、updated_atが勝手についてきますよね。これらはわざわざcsvファイルに書きたくないカラムです。でも.importだとこいつらも含めてcsvファイルに書かないといけない。それはめんどい。
そこでRailsの初期データ作る用のseeds.rbを使います。データベースに直接流し込むのではなくRailsの機能を使うわけですね。
seeds.rb用にコードを出力させる
とはいえdb/seeds.rbに直にcsvは書けないので、seeds.rbに書くコードを出力するスクリプトを作りました。seeds.rbで初期データを作る時は、
Hoge.create(:fuga => 1)
のように書きます。これをcsvから読んで出力できるようにします。
csv_to_seeds.rb
# coding: utf-8 require 'csv' CSV.foreach("./infos.csv") do |row| print "Info.create(" print ":no => #{row[0].to_i}" print ", :name => '#{row[1]}'" puts ")" end
infos.csv
1,江戸川 2,金田一 3,明智
csvのデータは番号(no)と名前(name)というカラムに対応します。そういうInfoモデルを作ったという設定で。実行結果がこれ。
実行結果をseeds.rbにリダイレクトすればok。
ruby csv_to_seeds.rb >> seeds.rb
あとはrake db:seedで初期データが出来ます。SQLite3使うために遠回りしたなぁ。