Парсинг данных в БД.

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
vv-off
Сообщения: 53
Зарегистрирован: 2018.01.12, 11:49

Парсинг данных в БД.

Сообщение vv-off »

Всем привет.
Для заполнении БД данными из файла (xml), делю данные на два массива,
один для insert (новые данные), второй для update (измененные данные, которые уже есть в бд).
Новые данные отслеживаю по некоему идентификатору, если в БД уже такой есть, то данные для обновления,
если нет, то для добавления.
Так вот, при добавлении новых данных в БД проблем нет Yii::$app->db->createCommand()->batchInsert
Подскажите как массово обновить данные по ключам, по типу batchInsert и условию WHERE IN (ключи)?

ЗЫ понятно что можно в цикле простым update сделать, но например у меня 4000 записей и то я сделаю 8 запросов (500 записей в файле), а то
4000 запросов к БД.
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: Парсинг данных в БД.

Сообщение rak »

перед тем, как пытаться сделать это через yii нужно задать себе вопрос, а как это должно выглядеть в обычном sql? ;)
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: Парсинг данных в БД.

Сообщение rak »

ну и вообще, закинуть разбор xml в очередь и 4к запросов будет совсем не страшно
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Парсинг данных в БД.

Сообщение unknownby »

vv-off писал(а): 2020.02.04, 13:55 один для insert (новые данные), второй для update (измененные данные, которые уже есть в бд).
Зачем таким заниматься? Выполни truncateTable и всё на insert
Идентификаторы записей в файле проставлены? Если да, то можно сделать как сказал.
vv-off
Сообщения: 53
Зарегистрирован: 2018.01.12, 11:49

Re: Парсинг данных в БД.

Сообщение vv-off »

unknownby писал(а): 2020.02.04, 15:26
vv-off писал(а): 2020.02.04, 13:55 один для insert (новые данные), второй для update (измененные данные, которые уже есть в бд).
Зачем таким заниматься? Выполни truncateTable и всё на insert
Идентификаторы записей в файле проставлены? Если да, то можно сделать как сказал.
Не могу, должна быть возможность как импорта, так и ручного ввода. Если сделаю truncateTable, то весь ручной ввод убью.
Думаю что откажусь от инкреметного поля в бд и перейду на uuid, тогда можно будет сделать batch insert on duplicate key update
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Парсинг данных в БД.

Сообщение unknownby »

vv-off писал(а): 2020.02.04, 15:30 Не могу, должна быть возможность как импорта, так и ручного ввода. Если сделаю truncateTable, то весь ручной ввод убью.
Думаю что откажусь от инкреметного поля в бд и перейду на uuid, тогда можно будет сделать batch insert on duplicate key update
Какой-то идентификатор ручного ввода есть? Отличаются ли записи ручного ввода от импортированных данных, может каким-нибудь статусом?
someweb
Сообщения: 552
Зарегистрирован: 2017.03.09, 10:12

Re: Парсинг данных в БД.

Сообщение someweb »

Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа. Роберт Шекли.
gbushmakin
Сообщения: 31
Зарегистрирован: 2019.06.20, 12:38

Re: Парсинг данных в БД.

Сообщение gbushmakin »

Да, сам пользуюсь всегда в таких случаях batch insert on duplicate key update. Бывает порой обновить нужно 10.000 строк, справляется на ура. Максимально наверное 40.000 строк обновлял. Для себя даже метод написал

Код: Выделить всё

    public function OnDuplicateKeyUpdate ($tablename, $updateData) {

         // получаем ключи с первой иттерации и будем использовать их в дальнейшем
        foreach ($updateData as $key) {
            $name_keys = array_keys($key);
            break;
        }


        foreach ($name_keys as $key) {
            $query .= "`{$key}` = VALUES(`{$key}`)";
            if($key != end($name_keys)) $query .= ", ";
        }

            $db = Yii::$app->db;
            $sql = $db->queryBuilder->batchInsert($tablename, $name_keys, $updateData);
            $result = $db->createCommand($sql . ' ON DUPLICATE KEY UPDATE ' . $query)->execute();

        if ($result) {
            return $result;
        } else {
            return false;
        }

    }
Работает так $this->OnDuplicateKeyUpdate(ИмяТаблицы, МассивДанных);
Массив данных должен быть такой, например:
[
['id' => 10, 'text' => 'new']
['id' => 15, 'text' => 'new2']
['id' => 20, 'text' => 'newwwww1232']
]
Где id - автоинкримент (или любое название инкримента)

ИЛИ ЖЕ, если нужно ДОБАВИТЬ НОВЫЕ, то без автоинкримента массив строк=>значений. Добавляет новые. Новый даже в случае, если автоинримента такого нет.

Главное чтобы весь массив был с одними и теми же ключами в одном порядке, потому что название строк там берется из первого массива

Получается полезно в обоих случаях: когда нужно массово обновить или когда массово добавить. Пользуюсь на разных движках.
vv-off
Сообщения: 53
Зарегистрирован: 2018.01.12, 11:49

Re: Парсинг данных в БД.

Сообщение vv-off »

Спасибо!
Ответить