実現したいこと
シーダー経由で、CSVからデータベースにデータの登録を行いたい
前提
LaravelでCSVの内容をシーダー経由でMysqlに登録したいです。
しかし、シーダーを読み込ませようとするとcreated_atカラムがテーブルに存在していないかのようなエラーが出てしまいます。
発生している問題・エラーメッセージ
bash
1#docker-compose exec app bash 2root@8340ff6d38bb:/work# php artisan db:seed --class=InquiryTableSeeder 3 4 Illuminate\Database\QueryException 5 6 7 8 9```php 10//InquiryTableSeeder.php 11<?php 12 13namespace Database\Seeders; 14use Illuminate\Support\Facades\DB; 15use DateTime; 16use Illuminate\Database\Seeder; 17use App\Models\Inquiry; 18use Illuminate\Support\Arr; 19 20class InquiryTableSeeder extends Seeder 21{ 22 /** 23 * Run the database seeds. 24 * 25 * @return void 26 */ 27 public function run() 28 { 29 //ここに読み込ませたいCSV 30 $file = new \SplFileObject(storage_path('app/private/csv/inquiries_migration.csv')); 31 $file->setFlags( 32 \SplFileObject::READ_CSV | 33 \SplFileObject::READ_AHEAD | 34 \SplFileObject::SKIP_EMPTY | 35 \SplFileObject::DROP_NEW_LINE 36 ); 37 38 foreach ($file as $i => $line) { 39 if ($i === 0) { 40 $headers = $line; 41 continue; 42 } 43 44 45 // ['created_at' => 'taro'] のようにヘッダ行とデータ行を結合 46 $values = array_combine($headers, $line); 47 48 // 空白文字を含む可能性があるカラムの値から空白文字を削除 49 $values['serial'] = trim($values['serial'] ?? ''); 50 $values['type'] = trim($values['type'] ?? ''); 51 52 53 54 55 if (isset($values['phoneNumber']) && !empty($values['phoneNumber'])) { 56 $phoneNumberWithoutHyphen = preg_replace('/[^0-9]/', '', $values['phoneNumber']); // 数字以外の文字列を除去 57 $values['PhoneNumberWithoutHyphen'] = $phoneNumberWithoutHyphen; 58 } 59 60 // 改行コードをリアル改行として扱う 61 $values['question'] = str_replace(['\n', '<br>'], "\n", $values['question']); 62 $values['answer'] = str_replace(['\n', '<br>'], "\n", $values['answer']); 63 64 65 // created_atカラムが存在し、空でない場合 66 if (isset($values['created_at']) && !empty($values['created_at'])) { 67 //inquiry_idが同じレコードが既にあるなら更新、なければ作成 68 Inquiry::updateOrCreate( 69 ['inquiry_id' => $values['inquiry_id']], 70 Arr::except($values, ['inquiry_id']) 71 ); 72 } else {//created_atカラムが空だったり想定されない値の場合は1970-01-01を入力 73 //$values['created_at'] = new DateTime('1970-01-01'); 74 75 //inquiry_idが同じレコードが既にあるなら更新、なければ作成 76 Inquiry::updateOrCreate( 77 ['inquiry_id' => $values['inquiry_id']], 78 Arr::except($values, ['inquiry_id']) 79 ); 80 81 } 82 } 83 84 } 85 86 }
試したこと
php artisan cache:clear
php artisan config:clear
サーバー再起動も行いましたが同じです。
気になる点としては、開発環境のMAC上で同じことを行ってもエラーにならないのに、
本番環境のubuntuの実機で同じことを行うとエラーになります。
本番環境にはsshに入っています。
追記
YT0014さんより指摘があった通り、
シーダー実行時のエラーに
おそらく、csvファイル上に存在するcreated_atの値と、現在のタイムスタンプの両方を入力しようとしてしまっているのではないかと思います。
csvファイル上のcreated_atだけを使いたいのですが、何か方法はないでしょうか。
モデル側でタイムスタンプの自動挿入を無効にする方法もあるかとは思いますが、それだと影響範囲が大きいので別の方法があればありがたいです。
補足情報(FW/ツールのバージョンなど)
Docker version 23.0.1, build a5ee5b1
docker-compose version 1.29.2, build unknown
Laravel8
PHP 8.0.28 (cli) (built: Mar 1 2023 13:21:15) ( NTS )
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。