📌

【Rails】CSVファイルをデータベースに投入するクラス

2021/02/24に公開

CSVファイルのデータをデータベースに投入するためのクラスを作成し,投入するまでの手順を記載します。

モデル名に対応するCSVファイルを用意するだけで簡単に投入できるように工夫しています。

1. 準備

  • バルクアップサートしたいので Activerecord-Import を追加
Gemfile
gem "activerecord-import"
ターミナル
bundle install
mkdir db/csv_data
touch lib/import_csv.rb
  • CSVファイルをデータベースに投入するクラスを作成
lib/import_csv.rb
require "csv"

class ImportCsv
  def self.execute(model:, file_name: nil)
    model_name = model.to_s.classify
    table_name = model_name.tableize
    file_name ||= table_name.singularize
    path = Rails.root.join("db/csv_data/#{file_name}.csv")

    list = []
    CSV.foreach(path, headers: true) do |row|
      list << row.to_h
    end
    # 与えられたモデルに CSVデータを投入
    model_name.constantize.import!(list, on_duplicate_key_update: :all)
    # 次に振る id を正常化
    ActiveRecord::Base.connection.execute("select setval('#{table_name}_id_seq',(select max(id) from #{table_name}))")
  end
end
  • CSVファイルを用意

例えば, Item モデルと items テーブルが存在する場合は, item.csvdb/csv_data 配下に配置して下さい。

1行目はテーブルのカラム名と合わせてください。例を記載します。

db/csv_data/item.csv
id,title,color
1,食費,#8fc511
2,水道光熱費,#f6d108
3,交通費,#7844d4

2. データベースへの投入

Rails コンソールを起動し,以下を実行すれば db/csv_data/item.csv ファイルを items テーブルに投入できます。

Railsコンソール
require "import_csv"
ImportCsv.execute(model: Item)

投入するCSVのファイル名を item_dev.csv など特別に指定したい場合は ImportCsv.execute(model: Item, file_name: "item_dev" ) に置き換えれば対応できるようにしています。

Discussion