@file2
improving further

Как сделать быстрый парсинг XML и запись в базу?

Как быстрее произвести сам парсинг и затем сделать insert в бд?
На данный момент использую такой алгоритм, но при больших файлах(и когда файлов много) читает xml и делает insert долго.
Есть ли другой алгоритм быстрее распарсить xml и сделать insert не по каждой записи а группой?
Например сразу записать все что есть в ZAP в client_table , потом DATA вusl_table

import xml.etree.cElementTree as ET
tree = ET.parse(filexml)
element_xml_root = tree.getroot()
dbcur = db.cursor()

for elem in element_xml_root.findall('ZAP'):
    idclient = elem.find('ID_CLIENT').text
    fam = elem.find('FAM').text
    im = elem.find('IM') .text
    ot = elem.find('OT') .text
    query_pac = dbcur.prepare('INSERT INTO client_table (idclient, fam, im, ot)'
                          ' VALUES (:idclient, : fam, : im, : ot)')
    dbcur.execute(query_pac, (idpac, fam, im, ot))
    for data in elem.findall('DATA'):
        code_usl = data.find('CODE') .text
        date_usl = data.find('DATE') .text
        price_usl = data.find('PRICE') .text
        query_usl = dbcur.prepare('INSERT INTO usl_table (idpac, code_usl, date_usl, price_usl)'
                          ' VALUES (:idpac, : code_usl, : date_usl, : price_usl)')
        dbcur.execute(query_usl, (idpac, code_usl, date_usl, price_usl))

db.commit()
dbcur.close()
  • Вопрос задан
  • 4457 просмотров
Решения вопроса 1
trapwalker
@trapwalker Куратор тега Python
Программист, энтузиаст
Прологируйте подробно вашу функцию и вы поймёте что больше тормозит.
Основных проблемы может быть три:
1) Долгий парсинг XML. Его время зависит от размера файла, а вставлять в базу вы начнете только по окончании парсинга. При этом весь файл в виде объектного дерева у вас будет в памяти. что может быть очень неэффективно.
2) Долгий поиск нужных элементов в дереве. Это сомнительно, что он тут будет существенно тормозить на фоне прочих процессов.
3) Долгая вставка из-за отдельных транзакций на каждую.

1,2) Первая проблема может быть решена потоковым чтением XML через SAX-парсер. На закрытие определенных тегов вешаются события, а объект-парсер накапливает данные в своём состоянии. Это позволит получать данные по мере чтения и парсинга файла, а не после. Вторая проблема, кстати, то же решается sax-парсером. Просто не будет дополнительных накладных расходов на обход построенного парсером дерева.

3) Можно попробовать cursor.executescript для пакетного исполнения запросов. Тут есть минус, нужно валидацию и экранирование данных делать руками и правильно. нужно бояться sql-инъекций.
Лучше использовать cursor.executemany. Вот, например про это на стэковерфлов: https://stackoverflow.com/questions/18244565/how-c...
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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