0
0

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 3 years have passed since last update.

RailsにFixturesで初期データを入れるためのyamlをCSVから作るスクリプト

Last updated at Posted at 2020-05-19

Railsのデータベースにデータを投入する方法はfixtures用のyamlファイルを作って、railsコマンドで入れる方法などがよく知られています。
ですが、現実的にはExcelなどで元データを用意してCSV等で扱うことが多いと思われます。
yamlコンバータなども試してみたけどfixtures keyを入れるのがうまくいかなかったので、自分で作りました。
エスケープ文字の処理とかなにもやってないので、元データがそういうものを扱う場合は適宜加工してください。

たとえば、1行目にカラム名が入ったこんな感じのCSVファイルがあったとして。

fruits.csv
id,item,price
1,りんご,100
2,みかん,80
3,バナナ,60
4,メロン,2000
5,いちご,300

Fixturesで扱うにはこういうyamlファイルが必要になります。

fruits.yml
data1:
  id: 1
  item: りんご
  price: 100

data2:
  id: 2
  item: みかん
  price: 80

data3:
  id: 3
  item: バナナ
  price: 60

data4:
  id: 4
  item: メロン
  price: 2000

data5:
  id: 5
  item: いちご
  price: 300

data1:のところがfixtures keyというやつで、データベースには反映されないけど、レコードごとにハッシュとしてユニークな値をつけなければいけないようです。

スクリプトはこんな感じです。
ExcelからCSVに変換したら、UTF-8でBOMが付いてしまったので、ファイルをopenするときにオプションが付いてます。

csv2yaml.rb
#!/use/bin/env ruby

filename = ARGV[0]

# UTF-8のBOMを消すオプション
file = open(filename, 'r:BOM|UTF-8')

# CSVファイルの先頭行を取得
column = file.gets.chomp.split(",")

# fixtures keyのプレフィックス(data)とそのあとに付けるカウンタ(num)
prefix = "data"
num = 1
str = ""

file.each do |line|
  unless line.strip == ""             ## 空白行を無視する
    str += "#{prefix}#{num}:\n"
    (0 .. column.length - 1).each do |i|
      str += "  #{column[i]}: #{line.chomp.split(",")[i]}\n"
    end
    str += "\n"
    num += 1
  end
end
print str

Shellから実行する時はこんな感じです。

$ ./csv2yaml.rb fruits.csv > fruits.yml

500行くらいのCSVデータの変換して問題なかったし、fixturesでも取り込めたので大丈夫なようです。
カラムが異なる複数のCSVファイルでも変換できました。

yamlのライブラリなどを使えばもっと簡単に作れるかも。

0
0
1

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?