【问题标题】:Import large csv file with laravel excel and postgresql使用 laravel excel 和 postgresql 导入大型 csv 文件
【发布时间】:2023-03-23 23:37:01
【问题描述】:

您好,我有一个包含 130.000 行的大型 csv 文件

我使用 laravel excel 3.1 和 laravel 5.8

导入类:

<?php

namespace App\Imports;

use App\UsoSuelo;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithBatchInserts;

class UsoSueloImport implements ToModel, WithHeadingRow, WithChunkReading, WithBatchInserts
{
    /**
    * @param array $row
    *
    * @return \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        return new UsoSuelo([
            'cod_pais'     => $row['cod_pais'],
            'cod_fundo'     => $row['cod_fundo'],
            'nom_fundo'     => $row['nom_fundo'],

        ]);
    }
    public function batchSize(): int
    {
        return 1000;
    }
    public function chunkSize(): int
    {
        return 1000;
    }
}

我使用控制器中的特征类:

    trait storeTrait{

    public function storeUsoSuelo($archivo) {
        Excel::import(new UsoSueloImport,$archivo); 
    }
    public function storeFundo($archivo) {
        Excel::import(new FundosImport,$archivo); 
    }
    public function storeFundoGrilla($archivo) {
        Excel::import(new FundosGrillasImport,$archivo); 
    }
    public function storeCuadrante($archivo) {
        Excel::import(new CuadrantesImport,$archivo); 
    }
}

这是我的 ImportController

class ImportController extends Controller
{
    use storeTrait  {
        storeUsoSuelo as storeUsoSuelos;
        storeFundo as storeFundos;
        storeFundoGrilla as storeFundoGrillas;
        storeCuadrante as storeCuadrantes;

    }
    public function store(Request $request)
    {
        $usoSuelo = 'uso_suelo.csv';
        $this->storeUsoSuelos($usoSuelo);

        $cuadrante = 'cuadrantes.csv';
        $this->storeCuadrantes($cuadrante);

        $fundo = 'mv_qav_fundos.csv';
        $this->storeFundos($fundo);

        $fundoGrilla = 'fundos_grilla.csv';
        $this->storeFundoGrillas($fundoGrilla);
}
}

我已经完成了测试,我的代码适用于少于 100 行的 csv 但是当我尝试使用 130,000 行时,它花费的时间太长了,我最终得到了以下错误:

"Maximum execution time of 60 seconds exceeded"

1 分钟后,数据库中只插入了 4000 行(postgresql)

【问题讨论】:

  • 您需要使用排队作业来处理 csv。执行时间错误来自max_execution_time PHP 设置。
  • 你好,如果我理解,碰巧我的最大时间如下: max_execution_time = 240 试试你给我的建议,但都没有,1分钟后只导入了4000行,我得到了错误我再次提到prntscr.com/s6yxnu
  • 这里有数千个关于长时间运行的 PHP 进程的问题,如果你搜索错误消息,或者类似“长时间运行的 PHP 进程”,你会找到其中的一些。摆弄max_execution_time 等是一种变通的解决方法。如果您使用的是 Laravel,那么您已经拥有内置的标准解决方案并且触手可及 - use queues。另一种选择是将 PHP 脚本写入run on the console,而不是在浏览器中。

标签: laravel postgresql csv laravel-excel


【解决方案1】:

我将这两行放在我的控制器中,在脚本的开头:

ini_set ('max_execution_time', 3600);
ini_set ('memory_limit', '2048M');

这样我解决了,我也把chunk从1000改成了5000,但是还是太长了,至少5分钟

【讨论】:

    【解决方案2】:

    您是否尝试过 league/csv 来自 The League of Extraordinary Packages 的这个包。

    如果您只需要对 CSV 的支持,而不是 xlsx 或其他 excel 类型。 从我读到的内容来看,这个包可能会给你带来更好的性能,来自 Maatwebsite 团队成员之一的this comment(你当前使用的包)也证实了这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      相关资源
      最近更新 更多