しっぽを追いかける Follow Tail !!

たまに趣味と、たまに情報系備忘録。

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モデルを作ったという設定で。実行結果がこれ。

f:id:tales_tail:20150720032810p:plain

 実行結果をseeds.rbにリダイレクトすればok。

ruby csv_to_seeds.rb >> seeds.rb

 あとはrake db:seedで初期データが出来ます。SQLite3使うために遠回りしたなぁ。