Open3

LaravelでPostgreSQLへ大量データをロードさせる

k8labk8lab
  • LaravelからPostgreSQLへ大量のデータを読み込みたい。
  • ケースとしてはアップロードされたExcelファイルを読み込み、マスタへ反映する事を想定する。
  • 制限としては主に管理者ユーザが利用する機能で同時にリクエストされる事が少ないものとする。
  • 以下の環境での動作を確認
    • Laravel 12
    • PHP 8.4(php-fpm)
    • PostgreSQL 17
    • Alpine
    • WSL2
k8labk8lab
  • このケースでまず実装されやすいのがLaravelのbulk insertを利用する方法
  • 実装は簡単だが、安心できない方法だ。
  • 問題としては、データ件数が多い場合にクエリ長が長くなりすぎてエラーが発生してしまう。
  • なのである程度のサイズに分割して繰り返し実行を行うようにする。
  • 一見問題なく動作するのだが、この手が使えるのは1レコードのサイズが固定であれば問題ないが、備考のように可変サイズのフィールドが存在すると破綻する。
  • ケースによってはタイムアウトとかメモリとかで破綻しかねない。
k8labk8lab
  • 想定ケースにおいての実装としてはPostgreSQLのCOPYコマンドを利用する方法がある
  • PHPのPDO PostgreSQL拡張モジュールを利用し、CSV形式を読み込ませる
  • 下記のコードのように一次元のカンマ区切りの配列を指定したテーブルへ読み込ませる事が出来る。
$csv = ["テスト, 1", "テスト2", 2];
DB::connection()->getPdo()->pgsqlCopyFromArray('テーブル名', $csv, ',');
  • 接続ユーザーにinsert権限さえあればよいのでPostgreSQLの設定を別途変更する必要はない。
  • もちろんこの場合、$csvのサイズが大きくなるとPHP側のメモリ制限に引っ掛かるので別途対策は必要です。