laravel excel с upserts, не обновляющими данные

У меня есть файл csv с данными внутри. Я хочу импортировать его в свою базу данных. Если в файле csv есть повторяющиеся данные, я не хочу, чтобы он создавал новые повторяющиеся записи, я хочу его обновить.

Но проблема в том, что создаются новые повторяющиеся записи.

Контроллер (сокращенно):

Excel::import(new FruitImport, $request->file('fruits_file'), \Maatwebsite\Excel\Excel::XLSX);

Файл импорта (сокращенно):

class FruitImport implements ToModel, WithUpserts, ... {
    public function model(array $row) {
        return new Fruit([
            'color' => $row[0],
            'taste' => $row[1],
            'smell' => $row[2],
            'name' => $row[3],
            'price' => $row[4],
            'supplier_id' => $row[5],
            ...
         ]);
    }

    public function uniqueBy() {
        return ['color', 'taste', 'smell', 'name'];
    }

    ...
}

Итак, в основном, если я импортирую файл csv, содержащий строки с одинаковым цветом, вкусом, запахом и именем, в свою базу данных, я хочу, чтобы он был обновлен. То же самое, если какая-либо запись в моей базе данных имеет одинаковые данные о цвете, вкусе, запахе и названии.

Моя таблица:

Field    | Type        | Key  | ...
id       | big int un..| Pri  |
color    | varchar(12) |      |
taste    | varchar(12) |      |
smell    | varchar(12) |      |
name     | char(20)    |      |
...

Я использую Laravel 8, Php 8.0.2 и Mysql 8. Laravel excel - это версия 3.1.

Мои ссылки:

https://laravel.com/docs/8.x/eloquent#upserts

https://docs.laravel-excel.com/3.1/imports/model.html#upserting-models

Любые идеи?


person Ricardinho    schedule 02.06.2021    source источник


Ответы (1)


Я не уверен, что Upserts в Laravel Excel верны что ты хочешь. В частности, в документации есть условие, которое (на мой взгляд) является чрезмерно ограничивающим.

Все базы данных, кроме SQL Server, требуют, чтобы столбцы uniqueBy имели первичный или уникальный индекс.

Чтобы импортировать данные электронной таблицы по своему усмотрению, вы всегда можете использовать ToCollection. Это даст вам полный контроль над сохранением записей.
https://docs.laravel-excel.com/3.1/imports/collection.html

Используйте метод updateOrCreate() для поиска существующих записей с указанными вами параметрами, передав их в первом массиве, а оставшиеся данные - во втором массиве. https://laravel.com/docs/8.x/eloquent#upserts

class FruitImport implements ToCollection ... 
{    
    public function collection(Collection $rows)
    {
        foreach ($rows as $row) 
        {
            Fruit::updateOrCreate(
                [
                    'color' => $row[0],
                    'taste' => $row[1],
                    'smell' => $row[2],
                    'name' => $row[3]
                ],
                [
                    'price' => $row[4],
                    'supplier_id' => $row[5],
                    ...
                ]
            );
        }
    }
}
person matticustard    schedule 02.06.2021
comment
не совсем то, что я искал, но действительно полезно. Спасибо - person Ricardinho; 07.06.2021