Я анализирую кучу больших XML-файлов в базе данных sqlite3 на python.Как я могу сказать, (хотя я очень открыт и ищу более производительные варианты), более производительным вариантом является executemany()
функция sqlite3 для вставок.
Суть того, что я делаю в данный момент, такова:следует:
document_dir = '/documents'
Document = named_tuple('Document', 'doc_id doc_title doc_mentioned_people ... etc')
People = named_tuple('People', 'doc_id first_name last_name ... ')
class DocumentXML(object):
"""
... there's some stuff here, but you get the idea
"""
def parse_document(path):
"""
This object keeps track of the current 'document' type element from a cElementTree.iterparse() elsewhere
I've simplified things here, but you can get the idea that this is providing a named tuple for a generator
"""
doc_id = _current_element.findall(xpath = '../id')[0].text
doc_title = _current_element.findall(xpath = '../title')[0].text
# parse lists of people here
doc_mentioned_people = People(first_name, last_name, ..., person_id)
#etc...
return Document(doc_id, doc_title, doc_mentioned_people, ..., etc)
def doc_generator():
documents = parse_document(document_dir)
for doc in documents:
yield doc.id, doc.title, ..., doc.date
# Import into Table 1
with cursor(True) as c:
c.executemany("INSERT INTO Document VALUES (?,?,?,?,?,?,?,?,?,?,?);", doc_generator())
def people_generator():
documents = parse_document(document_dir)
for doc in documents:
people = doc.people
yield people.firstname, people.lastname ..., people.eyecolor
# Import into Table 2
with cursor(True) as c:
c.executemany("INSERT INTO Document VALUES (?,?,?,?,?,?,?,?,?,?,?);", people_generator())
# This goes on for several tables...
Как видите, здесь ужасный уровень неэффективности.Каждый xml-файл анализируется снова и снова с тем же числом анализаторов, что и таблицы в базе данных.
Я хотел бы использовать только один синтаксический анализ XML (поскольку я могу получить всесоответствующую информацию в одном названном кортеже), но сохраняйте структуру как генератор, чтобы не увеличивать требования к памяти до невыполнимых уровней.
Есть ли хороший способ сделать это?
Мойпопытки вращаются вокруг использования executemany с оператором типа двойной вставки, например:
c.executemany("
INSERT INTO Document VALUES (?,?,?,?,?,?,?,?,?,?,?);
INSERT INTO People VALUES (?,?,?,?,?,?,?);
INSERT INTO Companies VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?);
INSERT INTO Oils VALUES (?,?,?,?,?,?,?);
INSERT INTO Physics VALUES (?,?,?,?,?,?,?,?,?,?,?)",
complete_data_generator())
Где complete_data_generator()
возвращает всю соответствующую структурированную информацию;Однако я знаю, что это, скорее всего, не сработает.
Есть ли лучший способ структурировать это для производительности?