Как осуществить импорт данных из файла Excel в базу данных Laravel 9, при этом производя проверку существующих записей по их уникальному идентификатору (ID)?

Как можно реализовать функциональность в Laravel-Excel для проверки существования продукта по ID при импорте из Excel-файла, так чтобы если продукт существует, обновлялась только его цена, а если нет — добавлялись все данные о новом продукте? Сейчас мой код перезаписывает информацию о продуктах в базу данных без проверки наличия продукта:

```php
return new Product([
    'id'     => $row[0],
    'name'    => $row[1],
    'price' => $row[2],
]);
```
  • 4 декабря 2023 г. 10:30
Ответы на вопрос 2
Для выполнения импорта данных из файла Excel в базу данных Laravel с проверкой уникальных записей, вы можете использовать пакет `Maatwebsite/Laravel-Excel`, который предоставляет удобный функционал для работы с Excel файлами.

В вашем случае, для обновления существующих продуктов и добавления новых, вам стоит использовать метод `upsert()` Eloquent, который доступен начиная с Laravel 8.x. Метод `upsert` позволяет обновить существующие записи, если они найдены, или добавить новые записи, если они не существуют. Для работы с Laravel-Excel вам нужно создать класс импорта, который реализует интерфейс `ToCollection`.

Пример класса импорта:

```php
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Illuminate\Support\Collection;
use App\Models\Product;

class ProductsImport implements ToCollection, WithHeadingRow
{
    public function collection(Collection $rows)
    {
        foreach ($rows as $row) {
            // Тут можно добавить дополнительные проверки на валидацию данных

            // Использование метода upsert для обновления или вставки записи
            // ID используется в качестве уникального ключа для поиска
            Product::upsert([
                'id'     => $row['id'],
                'name'   => $row['name'],
                'price'  => $row['price'],
            ], ['id'], ['price']); // ID указывается для поиска, цена - для обновления
        }
    }
}
```

Убедитесь, что у вас установлен пакет Laravel-Excel:

```shell
composer require maatwebsite/excel
```

Теперь вы можете использовать этот класс для импорта данных. Пример контроллера:

```php
use Maatwebsite\Excel\Facades\Excel;
use App\Imports\ProductsImport;

class ProductController extends Controller
{
    public function import(ImportRequest $request) // Используйте свой собственный Request для валидации, если необходимо
    {
        Excel::import(new ProductsImport, $request->file('your_excel_file'));

        return redirect('/')->with('success', 'All good!');
    }
}
```

Этот код позволит вам производить импорт данных из Excel файла, где в случае существования продукта будет обновлена только его цена, а при отсутствии продукта будет добавлена вся информация о нём. Убедитесь, что ваш Excel файл имеет строки с заголовками, соответствующими атрибутам модели `Product`.

Также, если вы хотите добавлять продукты в транзакциях, чтобы избежать частичного добавления данных в случае ошибок, можно добавить транзакции напрямую в метод `collection`:

```php
public function collection(Collection $rows)
{
    \DB::transaction(function () use ($rows) {
        foreach ($rows as $row) {
            // ...
        }
    });
}
```

Важно следить за тем, чтобы количество строк не превышало лимиты MySQL для одной транзакции, если вы делаете импорт больших объёмов данных.
Для тех кому интересно и может помочь в будущем. Я реализовал это с помощью метода updateOrcreate и файл ProductImport выглядит вот так:public function model(array $row){$product = Product::updateOrcreate(['article'    => $row[0],],['article'     => $row[0],'name'    => $row[1],'price'    => $row[2],]);}здесь мы проверяем наличие поля article и, если оно присутствует, обновляем данные.Иначе создаем новый продукт
Похожие вопросы