1
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?

Laravelのseederでcsvのデータを挿入する方法

Last updated at Posted at 2024-12-04

はじめに

Laravelのseederで大量のcsvのデータを挿入する際に詰まったので対処方法について記述します。
csvのデータ量が10000行程度であれば以下のようなシンプルなseederでデータを挿入することが可能です。

シンプルなSeederの作成

Laravel Seederを作成する

php artisan make:seeder CsvSeeder

Seederの実装

CsvSeeder.pfp
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class CsvSeeder extends Seeder
{
    public function run()
    {
        // CSVファイルのパス
        $filePath = database_path('seeders/data.csv');

        DB::transaction(function () use ($filePath) {
            // CSVファイルを開く
            if (($handle = fopen($filePath, 'r')) !== false) {
                $header = fgetcsv($handle); // ヘッダー行を取得

                while (($row = fgetcsv($handle)) !== false) {
                    $data = array_combine($header, $row);

                    // データベースに挿入
                    DB::table('users')->insert([
                        'name'  => $data['name'],
                        'email' => $data['email'],
                        'age'   => $data['age'],
                        'created_at' => now(),
                        'updated_at' => now(),
                    ]);
                }

                fclose($handle); // ファイルを閉じる
            }
        });
    }
}

Seederを実行する

php artisan db:seed --class=CsvSeeder

大量データをSeederで挿入する方法

挿入するcsvデータが大量にある場合、メモリ不足でエラーになる場合があります。
対策としては以下が考えられます。

PHPのメモリ制限を増やす

php.ini
ini_set('memory_limit', '512M');

バルククエリを使用し、データを分割処理をする

CsvSeeder.pfp
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class CsvSeeder extends Seeder
{
    public function run()
    {
        // CSVファイルのパス
        $filePath = database_path('seeders/data.csv');

        // バッチサイズ(1回の挿入処理でまとめるレコード数)
        $batchSize = 1000;
        $batchData = [];

        // トランザクション処理
        try {
            if (($handle = fopen($filePath, 'r')) !== false) {
                $header = fgetcsv($handle); // ヘッダー行を取得

                while (($row = fgetcsv($handle)) !== false) {
                    // ヘッダーと行データを組み合わせる
                    $data = array_combine($header, $row);

                    $batchData[] = [
                        'name'       => $data['name'],
                        'email'      => $data['email'],
                        'age'        => (int)$data['age'],
                        'created_at' => now(),
                        'updated_at' => now(),
                    ];

                    // バッチサイズに達したら挿入
                    if (count($batchData) >= $batchSize) {
                        DB::transaction(function () use (&$batchData) {
                            DB::table('users')->insert($batchData);
                            $batchData = []; // 挿入後にバッチデータをリセット
                        });
                    }
                }

                // 残りのデータを挿入
                if (!empty($batchData)) {
                    DB::transaction(function () use (&$batchData) {
                        DB::table('users')->insert($batchData);
                    });
                }

                fclose($handle); // ファイルを閉じる
            }
        } catch (\Exception $e) {
            Log::error("Error occurred while processing CSV: " . $e->getMessage());
        }
    }
}

上記対応に加えてcsvデータのバリデーションやエラーハンドリングなどを行うことでスムーズな対応が可能になります。

1
0
0

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
1
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?