Encoderast
@Encoderast
frontend пытается что-то делать в backend

Yii2 — массовая загрузка / выгрузка / обновление в БД?

Валар Моргулис!

Ищу какой нибудь гайд по массовому добавлению товаров (допустим у нас 1000 штук) через excel файл. Информация есть что через ActivRecord само собой разумеется это делается, а как именно не нашел

И также ищу гайды по интеграции с 1C, если есть какие нибудь, чтоб прям для чайников - буду рад

Подскажите зеленому, я всего как 2 месяца на php пишу))
  • Вопрос задан
  • 1364 просмотра
Решения вопроса 1
Все пишут про то, как распарсить xls, только вот самое узкое место в процессе совсем не в том месте.

Проблемы начинаются, когда надо с помощью activeRecord просохранять несколько тысяч моделей. Если делать это в цикле, как предлагают выше, то в один прекрасный момент сервер вам скажет пару ласковых и скинет операцию либо по таймауту, либо по памяти, даже если лимиты задрать.

Я использую два принципиально разных варианта:
1) В операции импорта генерировать массив с полями модели и отдавать его в SQL-запрос, в обход activeRecord.
Просто вставляем в базу кучу записей, при повторе ключа - обновляем. Он довольно быстрый, но мне не нравится, так как не очень удобно работать со сложными структурами. Ну и теряем при этом такие вещи, как обработку behaviors, валидацию полей из rules модели, события и т.д. Конечно, если все это очень надо, то это можно вручную вызвать, но тогда и смысла в варианте не много остается.

$db = Yii::$app->db;
$sql = $db->queryBuilder->batchInsert(self::tableName(), $fields, $fullarray);
 $product_insert_count = $db->createCommand($sql . ' ON DUPLICATE KEY UPDATE name = VALUES(name), group_id = VALUES(group_id), manufacturer = VALUES(manufacturer), fullname = VALUES(fullname), code = VALUES(code)')->execute(); //Возвращает количество вставленных записей


2) Очереди. Сейчас в основном этим вариантом пользуюсь.
https://github.com/yiisoft/yii2-queue
Парсим файл, для обработки каждого товара создаем задание, в котором проводим все нужные операции (проверку на необходимость обновления, обновление или создание новой модели и т.д.) и добавляем это задание в очередь. После формирования очереди консольной командой запускаю выполнение очереди.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
slo_nik
@slo_nik Куратор тега Yii
Добрый день.
Для того, чтобы из exel файла добавить товары в базу, как уже подсказали, Вам нужно расширение PHPExcel.
При помощи этого расширения Вы считываете данные с файла, заполняете нужную модель и сохраняете данные в базу.
Приблизительно так:
class ProductsImportController extends Controller
{
    public function actionImport()
    {
        $file = (object)Yii::$app->request->post('FlightsImport'); // получаете имя файла

        $fileInput = Yii::getAlias('@webroot') . '/uploads/import_file/' . substr(strrchr($file->importfile, '/'), 1); // полный путь к файлу
        /* читаете файл */
        $objInputType = \PHPExcel_IOFactory::identify($fileInput);
        $objReader = \PHPExcel_IOFactory::createReader($objInputType);
        $objExcel = $objReader->load($fileInput);

        $sheet = $objExcel->getSheet(0);
        $highestRow = $sheet->getHighestRow();
        $highestColumn = $sheet->getHighestColumn();

        for($row = 1; $row <= $highestRow; $row++){
            if($row == 1) continue;
            $rowData = $sheet->rangeToArray('A'.$row.':'.$highestColumn.$row, null, true, false);
            // print_r($rowData); 
            // объект модели, которую надо заполнить
            $flights = new FlightsImport();
            // заполняете нужные атрибуты
           $flights->title = FlightsImport::findAirlineId($rowData[0][3]); // название компании
            $flights->save(false);
        }
    }
}

Чтобы понять, что это за массив $rowData[0][3] сделайте в методе print_r($rowData) и увидите, что и какие данные Вы получили из файла.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы