Функцию для сохранения данных в базе данных MySQL (используя OurSQL)


Я парсинг огромный XML-файл. В ней содержится несколько миллионов записей статьи вроде этой:

<article key="journals/cgf/HaeglerWAGM10" mdate="2010-11-12">
  <author>Simon Haegler</author>
  <author>Peter Wonka</author>
  <author>Stefan Müller Arisona</author>
  <author>Luc J. Van Gool</author>
  <author>Pascal Müller</author>
  <title>Grammar-based Encoding of Facades.</title>
  <pages>1479-1487</pages>
  <year>2010</year>
  <volume>29</volume>
  <journal>Comput. Graph. Forum</journal>
  <number>4</number>
  <ee>http://dx.doi.org/10.1111/j.1467-8659.2010.01745.x</ee>
  <url>db/journals/cgf/cgf29.html#HaeglerWAGM10</url>
</article>

Я шаг через файл и разбирать эти статьи с помощью lxml. Если я дам код без хранение товаров в моей базе данных он делает около 1000 записей в ~3 секунды. Но если я активирую хранение которых осуществляется ниже она составляет около 10 записей в секунду. Это нормально? Я помню разбор после того, как файл, и базу данных не был таким узким местом. Но у меня другой подход... (если смотреть через мои файлы, чтобы найти его)

def add_paper(paper, cursor):
    questionmarks = str(('?',)*len(paper)).replace("'", "") # produces (?, ?, ?, ... ,?) for oursql query
    keys, values = paper.keys(), paper.values()
    keys = str(tuple(keys)).replace("'", "") # produces (mdate, title, ... date, some_key)
    query_paper = '''INSERT INTO dblp2.papers {0} VALUES {1};'''.\
                    format(keys, questionmarks)
    values = tuple(v.encode('utf8') for v in values)
    cursor.execute(query_paper, values)
    paper_id = cursor.lastrowid
    return paper_id

def populate_database(paper, authors, cursor):
    paper_id = add_paper(paper, cursor)
    query_author ="""INSERT INTO dblp2.authors (name) VALUES (?) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)"""
    query_link_table = "INSERT INTO dblp2.author_paper (author_id, paper_id) VALUES (?, ?)"
    for author in authors:
        cursor.execute(query_author, (author.encode('utf8'),))
        author_id = cursor.lastrowid
        cursor.execute(query_link_table, (author_id, paper_id))

Редактировать:

Я был в состоянии сузить проблему до тех трех курсор.выполнитьС. Возможно, это проблема базы данных. Я попрошу на переполнение стека, если у кого-то есть идеи, почему это так медленно. Между тем мне было бы интересно, если код может быть переработан, чтобы быть более подходящие для Python. Любые идеи?

Правка 2:

Если использовать подобный подход, как мне хранить строку для каждой строки в базе данных, не используйте InnoDB механизм. Это медленнее на порядки. Код снова ускоряется, после того как я поменял двигатель.



1079
2
задан 7 июля 2011 в 04:07 Источник Поделиться
Комментарии
1 ответ

Вы можете попробовать делать все в транзакции. Это может быть быстрее. Я думаю, что с InnoDB можно создать совершении сделки за каждое заявление, которое будет медленно.

keys = str(tuple(keys)).replace("'", "")

Это странный способ сделать это, использовать

keys = '(%s)' % ','.join(keys)

3
ответ дан 8 июля 2011 в 08:07 Источник Поделиться