Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Парсинг xls и добавление в MySQL
Форумы портала PHP.SU » PHP » Напишите за меня, пожалуйста » Парсинг xls и добавление в MySQL

Страниц (1): [1]
 

1. Ulinell - 30 Мая, 2016 - 22:19:10 - перейти к сообщению
Добрый день!
Имеется огромный файл xls, более 20тыс. Строк. Парсю его phpexcel, далее идут проверки. Если такой артикул имеется, то обновляем некоторые позиции по нему, если отсутсвует, добавляем в базу.
Суть в том, что при таком подходе не хватает ресурса сервера, файл грузится очень долго.
Например если тупо прогонять и добавлять во временную таблицу, все происходит довольно быстро.
Вообщем, посоветуйте, как реализовать обновление/добавление с минимальной нагрузкой.
2. Мелкий - 30 Мая, 2016 - 22:28:48 - перейти к сообщению
Читать во временную таблицу. Потом парой запросов мержить с имеющимися данными.
3. Ulinell - 30 Мая, 2016 - 22:33:20 - перейти к сообщению
Мелкий пишет:
Читать во временную таблицу. Потом парой запросов мержить с имеющимися данными.

Процедурой?
4. Мелкий - 31 Мая, 2016 - 09:35:59 - перейти к сообщению
Быстрее всего - LOAD DATA INFILE. Но это про CSV и кусок головной боли с валидацией значений.
С нормальной валидацией и тоже за обозримое время работы - create temporary table, затем читаете файл на приложении, проверяете данные (но не проверяете имеющиеся данные) и делаете insert в эту временную табличку (лучше объединять в один запрос несколько values). Затем, если критичных ошибок не было в данных, делаете 3 запроса для синхронизации таблиц: update на две таблицы по inner join для данных, которые есть и там и там, но, возможно, надо их обновить. insert ... select where not exists для данных, которые надо дописать. delete where not exists для данных, которые надо удалить (или update с пометкой, что эти строки были, но потом их удалили).

Процедуру написать можно, но зачем? Только будет мешаться.
5. Dastor - 31 Мая, 2016 - 10:26:58 - перейти к сообщению
1. Если есть возможность, то лучше отказаться от phpexcel. Использовать парсер, например, на питоне (пример http://strife.pl/2014/12/converting-large-xls-xlsx-files-to-csv-using-python/).
И парсить в csv.
Если же нет, то xls с помощью phpexcel парсим сразу в csv. В phpexcel есть класс PHPExcel_Writer_CSV.
2. В бд создаем промежуточную таблицу. По структуре такую же, как таблица назначения + доп колонки: flag (см п.5), error. Таблица не временная, чтобы можно было показать промежуточный результат оператору/администратору (как минимум показать записи с ошибками).
3. Парсим xls в csv. Далее построчно читаем файл с помощью fgetcsv, проверяем данные, записываем строчку в другой csv файл! Если есть ошибки, то добавляем еще сообщение об ошибке (которое должно в п.4 попасть в колонку error).
4. После того как проверили прошли по всем строчкам, загружаем с помощью LOAD DATA INFILE в промежуточную таблицу.
Пункты 3 и 4 работают быстрее чем, если бы писали построчно в бд.
5. Далее нам надо определить какие данные вставлять, а какие обновлять. Если поле артикул - pk, то в этом случае проще. Можно использовать insert select on duplicate key update.
Если же нет, то необходимо сравнить данные в двух таблицах и выставить значение в колонке flag. Далее на основе flag, апдейтим и инсертим записи.
6. Ismail - 26 Июня, 2016 - 19:44:48 - перейти к сообщению
Можно посмотреть кусок кода, который обрабатывает xls?

 

Powered by ExBB FM 1.0 RC1