Laravel で CSV ファイルから DB seed する
はじめに
Laravel で CSV ファイルをもとに DB seed する方法を整理した。
TL;DR
SplFileObject
で読み込んでforeach
で 1行ずつ処理- 1行目はヘッダ行 = DB カラム名
- ヘッダ行とデータ行を
array_combine
で合成 - 合成した配列を使ってレコードの 検索/作成/更新 を行えば OK
updateOrCreate
が便利
- Bulk insert/update には未対応なので、大量データの処理には向かないかも
目次
環境・条件
1 | $ grep -i pretty /etc/os-release |
詳細
前提条件
CSV ファイル 1行目の内容を、対象テーブルのカラム名と一致させておくこと。
完成形
database/seeds/csvs/users.csv
に以下のような CSV ファイルを配置。
(配置場所は適当なので、各自で適宜変更)
1 | name,age,hobby |
database/seeds/UsersTableSeeder.php
1 |
|
ざっくり解説
CSV の読み込み
1 | $file = new \SplFileObject(database_path('seeds/csvs/users.csv')); |
CSV の読み込み処理は Laravelで大容量CSVファイルをSplFileObjectクラスで確実に処理する を利用しているので、そちらを見る方が良い。
foreach
で 1行ずつ処理している。
DB 用の配列作成
1 | foreach ($file as $i => $line) { |
1行目はヘッダ行として抽出し、array_combine
を使って、ヘッダとデータを結合する。
2行目の処理時の $values
は下記のようになる
1 | [ |
レコードの 作成/更新
1 | // 'name' で検索し、レコードが無ければ作成、有れば更新 |
updateOrCreate
を使って、検索/作成/更新 を実施。
第一引数(Array)が検索条件、第二引数(Array)が 作成/更新 に使うデータ。(たぶんやらなくても良い気がするが) Arr::except()
で、検索に使った条件は除外している。
検索条件が複数ある場合は Arr::only()
を使って、下記のようにするのが楽。
1 | // 'name' AND 'age' で検索し、レコードが無ければ作成、有れば更新 |
この部分はプロジェクトなどで条件違うはずなので、create
のみ実施にする、など適宜変更。
まとめ
SplFileObject
で読み込んでforeach
で 1行ずつ処理- 1行目はヘッダ行 = DB カラム名
- ヘッダ行とデータ行を
array_combine
で合成 - 合成した配列を使ってレコードの 検索/作成/更新 を行えば OK
updateOrCreate
が便利
- Bulk insert/update には未対応なので、大量データの処理には向かないかも
その他・メモ
最初は laravel-csv-seederを使ってseedデータを登録する(そしてcreate or updateしたい) - Qiita を参考に、Flynsarmy/laravel-csv-seeder を使おうかと考えていたが、最終コミットが 2017/10/31 なので自前で頑張る方式に変更した。
参考文献
- Laravelで大容量CSVファイルをSplFileObjectクラスで確実に処理する
- PHP: array_combine - Manual
- ヘルパ 5.8 Laravel
- Eloquent: Getting Started - Laravel - The PHP Framework For Web Artisans
関連記事
- Laravel で現在の URL 取得方法まとめ
- Laravel で Cookie を使う(参照/設定/削除)
- Laravel で PDF ファイルをブラウザで開く
- Laravel で withCount と having を使って絞り込み
- Laravel で「開始日時 < 終了日時」であることをバリデーションする
- Laravel で生 SQL を実行
- JavaScript で URL のクエリパラメータを操作する方法
- jQuery Select2 で、初期値の設定と選択状態のクリア