Импорт 70 тыс .+ строк в базу данных из CSV с эффективной памятью и временем выполнения - PullRequest
0 голосов
/ 27 апреля 2020

Могу ли я получить идею; Как я могу импортировать 70k + строк в базу данных из CSV, избегая большого использования памяти и времени в Laravel (PHP)

Часть моего кода, как я пытаюсь импортировать:

                $reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
                $reader->setInputEncoding('UTF-8');


                $spreadsheet = $reader->load($localpath);

                $spreadsheet = $spreadsheet->getActiveSheet()->toArray();
                $collection = LazyCollection::make($spreadsheet);

               if($key==null){
                  $key = array_map('trim', $collection->first());
                  $key_count=count($key);
               }

               $collection = $collection->except(0);

               foreach($collection as $row){
                if(count($row)==$key_count && !containsOnlyNull($row)){
                    $array[] = array_combine($key, $row);
                }
              }

Ответы [ 2 ]

2 голосов
/ 27 апреля 2020

Для этого можно использовать laravel-excel с чтением порции https://docs.laravel-excel.com/3.1/imports/chunk-reading.html

Чтобы уменьшить это увеличение использования памяти, вы можете использовать проблему WithChunkReading. Это будет читать электронную таблицу по частям и контролировать использование памяти.

Это пример кода, который вы можете написать:

namespace App\Imports;

use App\User;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithChunkReading;

class UsersImport implements ToModel, WithChunkReading
{
    public function model(array $row)
    {
        return new User([
            'name' => $row[0],
        ]);
    }

    public function chunkSize(): int
    {
        return 1000;
    }
}
0 голосов
/ 30 апреля 2020

Мне удалось импортировать этот файл с минимальным использованием памяти и времени с помощью LazyCollection. Вот пример кода, как я это сделал:

    LazyCollection::make(function () use (&$csv_data,$key_count){
        $datas = $csv_data;
        foreach($datas as $line)
        {
            if(count($line)==$key_count && !containsOnlyNull($line)){
                yield $line;
            }
        }
    })
    ->chunk(1000)
    ->each(function ($lines) use (&$import_info, $user_id, $country, $csv_fields, $key, $total, $products,$allProducts, $sync_id,$import_id){
}):
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...