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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Парсинг xls и добавление в MySQL

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
Ulinell
Отправлено: 30 Мая, 2016 - 22:19:10
Post Id


Новичок


Покинул форум
Сообщений всего: 2
Дата рег-ции: Май 2016  


Помог: 0 раз(а)




Добрый день!
Имеется огромный файл xls, более 20тыс. Строк. Парсю его phpexcel, далее идут проверки. Если такой артикул имеется, то обновляем некоторые позиции по нему, если отсутсвует, добавляем в базу.
Суть в том, что при таком подходе не хватает ресурса сервера, файл грузится очень долго.
Например если тупо прогонять и добавлять во временную таблицу, все происходит довольно быстро.
Вообщем, посоветуйте, как реализовать обновление/добавление с минимальной нагрузкой.
 
 Top
Мелкий Супермодератор
Отправлено: 30 Мая, 2016 - 22:28:48
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Читать во временную таблицу. Потом парой запросов мержить с имеющимися данными.


-----
PostgreSQL DBA
 
 Top
Ulinell
Отправлено: 30 Мая, 2016 - 22:33:20
Post Id


Новичок


Покинул форум
Сообщений всего: 2
Дата рег-ции: Май 2016  


Помог: 0 раз(а)




Мелкий пишет:
Читать во временную таблицу. Потом парой запросов мержить с имеющимися данными.

Процедурой?
 
 Top
Мелкий Супермодератор
Отправлено: 31 Мая, 2016 - 09:35:59
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




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

Процедуру написать можно, но зачем? Только будет мешаться.


-----
PostgreSQL DBA
 
 Top
Dastor
Отправлено: 31 Мая, 2016 - 10:26:58
Post Id


Гость


Покинул форум
Сообщений всего: 66
Дата рег-ции: Окт. 2014  


Помог: 3 раз(а)




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, апдейтим и инсертим записи.
 
 Top
Ismail
Отправлено: 26 Июня, 2016 - 19:44:48
Post Id



Новичок


Покинул форум
Сообщений всего: 46
Дата рег-ции: Сент. 2012  


Помог: 0 раз(а)




Можно посмотреть кусок кода, который обрабатывает xls?
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Напишите за меня, пожалуйста »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB