Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працює ImportAction у Filament і які ризики має імпорт CSV?

ImportAction дає користувачу завантажити CSV, зіставити його колонки з полями моделі й імпортувати рядки у фоні. Рядки, що не пройшли валідацію, збираються в окремий CSV «невдалих рядків» для завантаження.

Підготовка:

php artisan make:queue-batches-table
php artisan make:notifications-table
php artisan vendor:publish --tag=filament-actions-migrations
php artisan migrate
php artisan make:filament-importer Product --generate

Імпорт використовує пакети джоб (job batches) і сповіщення в базі даних - без воркера черги нічого не відбудеться.

Імпортер:

use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;

class ProductImporter extends Importer
{
    protected static ?string $model = Product::class;

    public static function getColumns(): array
    {
        return [
            ImportColumn::make('sku')->requiredMapping()->rules(['required', 'max:32']),
            ImportColumn::make('name')->requiredMapping()->rules(['required', 'max:255']),
            ImportColumn::make('price')->numeric()->rules(['numeric', 'min:0']),
            ImportColumn::make('category')->relationship(resolveUsing: 'slug'),
        ];
    }

    public function resolveRecord(): ?Product
    {
        // оновлювати наявні товари за SKU, нові - створювати
        return Product::firstOrNew(['sku' => $this->data['sku']]);
    }
}
ImportAction::make()
    ->importer(ProductImporter::class)
    ->chunkSize(250)
    ->maxRows(50_000);

CSV ділиться на частини (за замовчуванням по 100 рядків), кожна обробляється окремою джобою.

Ризики й як їх закрити:

  • немає авторизації кожного запису. Імпорт не викликає політики: хто може запустити імпорт, той створить чи оновить будь-який запис, який поверне resolveRecord(). Для недовірених користувачів перевірки треба додати в хуки beforeCreate() / beforeUpdate() імпортера;
  • resolveRecord() за слабким ключем (назва, email без нормалізації) - дублікати чи перезапис чужих даних;
  • CSV-формули. У файлі невдалих рядків значення лишаються як були. Комірка =HYPERLINK(...) чи =cmd|..., відкрита в Excel, може виконатися як формула. Варто попереджати користувачів або очищати значення, що починаються з =, +, -, @;
  • файл невдалих рядків за замовчуванням може завантажити лише користувач, що запустив імпорт. Власна політика ImportPolicy замінює цю логіку повністю - перевірку автора треба повторити в ній;
  • розмір. maxRows() і розумний chunkSize() захищають від файлу на мільйони рядків, що «покладе» чергу;
  • кастинг перед валідацією - ціни з комою (12,50) чи дати в дд.мм.рррр треба привести в castStateUsing(), інакше всі рядки впадуть на валідації.

Докладніше в документації: Імпорт

Схожі питання