Laravel Eloquent Error (SQLSTATE [22P02]: неверное текстовое представление: 7 ОШИБКА: неверный синтаксис ввода для целого числа) при импорте большого файла CSV - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь импортировать csv-файл со 130k строками, я делаю это с laravel excel, но это занимает много времени, поэтому я решил попробовать библиотеку fast-excel и csv league. С небольшим файлом все 3 библиотеки были импортированы правильно. Но с файлом CSV 130k, fast-excel и csv league выдается следующая ошибка:

"SQLSTATE[22P02]: Invalid text representation: 7 ERROR:  la sintaxis de entrada no es válida para integer: «» (SQL: insert into "uso_suelo" ("cod_pais", "cod_fundo", "nom_fundo", "cod_uso_suelo", "dsc_uso_suelo", "cod_rodal", "cod_especie", "dsc_especie", "ano_plantacion", "cod_esquema", "dsc_esquema", "dsc_restriccion_suelo", "sup_ha", "cod_z_cpino", "cod_z_prod", "cod_sz_prod", "dsc_sz_prod", "id_area_us", "updated_at", "created_at") values (90, 5196, LA PATAGUA, 4050, CORTAFUEGO, 0, , , , , , SIN RESTRICCION, 0.32, 7, 4, 17, NAHUELBUTA INTERIOR ALTA, 129660, 2020-04-29 10:45:24, 2020-04-29 10:45:24) returning "id")

При переносе таблицы я определил все поля как nullable

This код с библиотекой CSV лиги:

        $csv = Reader::createFromPath(storage_path('/app/uso_suelo.csv'));
        $csv->setHeaderOffset(0); //set the CSV header offset
        $records = $csv->getRecords();
        foreach ($records as $offset => $record) {  
            UsoSuelo::create([
                'cod_pais'     => $record['COD_PAIS'],
                'cod_fundo'     => $record['COD_FUNDO'],
                'nom_fundo'     => $record['NOM_FUNDO'],
                'cod_uso_suelo'     => $record['COD_USOSUELO'],
                'dsc_uso_suelo'     => $record['DSC_USOSUELO'],
                'cod_rodal'     => $record['COD_RODAL'],
                'cod_especie'     => $record['COD_ESPECIE'],
                'dsc_especie'     => $record['DSC_ESPECIE'],
                'ano_plantacion'     => $record['ANO_PLANTACION'],
                'cod_esquema'     => $record['COD_ESQUEMA'],
                'dsc_esquema'     => $record['DSC_ESQUEMA'],
                'dsc_restriccion_suelo'     => $record['DSC_RESTRICCION_SUELO'],
                'sup_ha'    => $record['SUP_HA'], 
                'cod_z_cpino'    => $record['COD_Z_CPINO'],
                'cod_z_prod'    => $record['COD_Z_PROD'], 
                'cod_sz_prod' => $record['COD_SZ_PROD'],
                'dsc_sz_prod' => $record['DSC_SZ_PROD'],
                'id_area_us' => $record['ID_AREA_US']
            ]);

}

И это с fast-excel:

$usoSuelo = (new FastExcel)->import(storage_path('/app/uso_suelo.csv'), function ($line) {
            return UsoSuelo::create([
                'cod_pais'     => $line['COD_PAIS'],
                'cod_fundo'     => $line['COD_FUNDO'],
                'nom_fundo'     => $line['NOM_FUNDO'],
                'cod_uso_suelo'     => $line['COD_USOSUELO'],
                'dsc_uso_suelo'     => $line['DSC_USOSUELO'],
                'cod_rodal'     => $line['COD_RODAL'],
                'cod_especie'     => $line['COD_ESPECIE'],
                'dsc_especie'     => $line['DSC_ESPECIE'],
                'ano_plantacion'     => $line['ANO_PLANTACION'],
                'cod_esquema'     => $line['COD_ESQUEMA'],
                'dsc_esquema'     => $line['DSC_ESQUEMA'],
                'dsc_restriccion_suelo'     => $line['DSC_RESTRICCION_SUELO'],
                'sup_ha'    => $line['SUP_HA'], 
                'cod_z_cpino'    => $line['COD_Z_CPINO'],
                'cod_z_prod'    => $line['COD_Z_PROD'], 
                'cod_sz_prod' => $line['COD_SZ_PROD'],
                'dsc_sz_prod' => $line['DSC_SZ_PROD'],
                'id_area_us' => $line['ID_AREA_US']
            ]);
        });

Миграция:

Schema::create('uso_suelo', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->integer('cod_pais')->nullable();
    $table->integer('cod_fundo')->nullable();
    $table->string('nom_fundo',100)->nullable();
    $table->integer('cod_uso_suelo')->nullable();
    $table->string('dsc_uso_suelo',100)->nullable();
    $table->integer('cod_rodal')->nullable();
    $table->integer('cod_especie')->nullable();
    $table->string('dsc_especie',100)->nullable();
    $table->integer('ano_plantacion')->nullable();
    $table->integer('cod_esquema')->nullable();
    $table->string('dsc_esquema',100)->nullable();
    $table->string('dsc_restriccion_suelo',100)->nullable();
    $table->float('sup_ha',8,2)->nullable();
    $table->integer('cod_z_cpino')->nullable();
    $table->integer('cod_z_prod')->nullable();
    $table->integer('cod_sz_prod')->nullable();
    $table->text('dsc_sz_prod')->nullable();
    $table->integer('id_area_us')->nullable();
    $table->timestamps();
});

Я знаю, что ошибка из-за пустых полей, но с 130 тыс. строк, я должен позволить это опустить. Странно то, что при импорте их с laravel -excel этого не происходит, база данных - postgresql, а версия laravel - 5.8

1 Ответ

0 голосов
/ 29 апреля 2020

Проблема в том, что вы создаете целочисленный столбец. но вы пытаетесь сохранить строку. Вы можете указать значение как float или integer

(float) $line['COD_PAIS']

, также вы вызываете запрос на вставку 130K !. Я бы посоветовал вам присвоить значение массиву перед вызовом insert

$data = [];
foreach ($records as $offset => $record) {
  $data[] = [
              'cod_pais' => $record['COD_PAIS'],
              'cod_fundo' => $record['COD_FUNDO'],
              'nom_fundo' => $record['NOM_FUNDO'],
               ...
            ]
}
UsoSuelo::insert($data);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...