使用 laravel excel 和 postgresql 导入大型 csv 文件
Import large csv file with laravel excel and postgresql
您好,我有一个包含 130.000 行的大型 csv 文件
我用的是laravelexcel3.1和lavaravel 5.8
导入class:
<?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;
}
}
然后我使用控制器的特征 class:
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)
我将这两行放在我的控制器中,在脚本的开头:
ini_set ('max_execution_time', 3600);
ini_set ('memory_limit', '2048M');
这样我就解决了,我也把chunk从1000改成了5000,但是还是太长了,至少5分钟
你试过The League of Extraordinary Packages的这个包league/csv
吗?
如果您只需要支持 CSV,而不是 xlsx 或其他 excel 类型。
从我读到的这个包可能会给你更好的性能,this comment 来自 Maatwebsite 团队成员之一(你当前正在使用的包)也证实了这一点。
您好,我有一个包含 130.000 行的大型 csv 文件
我用的是laravelexcel3.1和lavaravel 5.8
导入class:
<?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;
}
}
然后我使用控制器的特征 class:
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)
我将这两行放在我的控制器中,在脚本的开头:
ini_set ('max_execution_time', 3600);
ini_set ('memory_limit', '2048M');
这样我就解决了,我也把chunk从1000改成了5000,但是还是太长了,至少5分钟
你试过The League of Extraordinary Packages的这个包league/csv
吗?
如果您只需要支持 CSV,而不是 xlsx 或其他 excel 类型。 从我读到的这个包可能会给你更好的性能,this comment 来自 Maatwebsite 团队成员之一(你当前正在使用的包)也证实了这一点。