2015-10-14 6 views
1

Я написал следующий код для вставки данных в MEMSql, который имеет почти аналогичный синтаксис, как в MySQL.Внедрение пакетной вставки для повышения производительности

def get_connection(db=DATABASE): 
    """ Returns a new connection to the database. """ 
    return database.connect(host=HOST, port=PORT, user=USER, password=PASSWORD, database=db) 



def insert_data(data): 
    print 'inserting data...' 

    for item in data: 
     vars_to_sql = [] 
     keys_to_sql = [] 
     print(item) 
     for key,value in item.iteritems(): 
      if key == '__osHeaders': 
       value = str(value) 
      if isinstance(value, unicode): 
       vars_to_sql.append(value.encode('ascii', 'ignore')) 
       keys_to_sql.append(key.encode('ascii', 'ignore')) 
      else: 
       vars_to_sql.append(value) 
       keys_to_sql.append(key) 

     keys_to_sql = ', '.join(keys_to_sql) 
     with get_connection() as conn: 

      c = conn.execute("INSERT INTO tablename (%s) VALUES %r" % (keys_to_sql, tuple(vars_to_sql),)) 
      print c 

Имена полей не могут быть жестко закодированы, поскольку они могут меняться в соответствии с данными, которые я получаю с другого конца. В любом случае, это словарь, который я повторяю здесь. Поскольку эта единственная вставка очень медленная, мне нужно взять размер партии в качестве переменной, сформировать оператор запроса и вставить его соответственно. Таким образом, запрос для размера партии 2 будет INSERT INTO tablename col1, col2 VALUES ('a', 'b'),('c','d')

Пожалуйста, помогите мне, как представить его здесь.

+0

Возможно, посмотрите http://stackoverflow.com/a/6482610/3207406 – oliverpool

+0

Или, может быть, http://stackoverflow.com/questions/8134602/psycopg2-insert-multiple-rows-with-one-query – oliverpool

+0

Второй не задает поля. 1-й я должен получить копию данных, которые мне нужны, и выполнить. Почему я не могу сделать это в том же словаре, что у меня есть –

ответ

2

Если вы используете библиотеку MemSQL Python вам может использовать вспомогательный помощник multi_insert, указанный в пакете memsql.common.query_builder. Например:

from memsql.common.query_builder import multi_insert 
from memsql.common.database import connect 

sql, params = multi_insert("my_table", { "foo": 1 }, { "foo": 2 }) 
# sql = 'INSERT INTO `my_table` (`foo`) VALUES (%(_QB_ROW_0)s), (%(_QB_ROW_1)s)' 
# params = {'_QB_ROW_0': [1], '_QB_ROW_1': [2]} 

with connect(...) as conn: 
    conn.execute(sql, **params) 

Обратите внимание, что multi_insert требует, чтобы каждая запись имеет тот же набор столбцов, определенных, так как он переводит его на вставку на основе кортежа для запроса.

+0

OP: 'Имена полей также меняют, для которых я использую keys_to_sql, чтобы определить их. Ваш ответ: 'Обратите внимание, что для multi_insert требуется, чтобы каждая запись имела одинаковый набор столбцов', поэтому я не думаю, что это решит вопрос – oliverpool

+0

, но у вас есть хорошая точка:' multi_insert', кажется, 'bulk_insert' для memsql! Просто нужно проверить, принимает ли он значения DEFAULT :-) – oliverpool

+0

Я получаю строку Json, которую я конвертирую в Список словарей '[{" foo ": 1}, {" foo ": 2}]' using 'json. load() 'Так как мне взять из этого для ввода этой функции' multi_insert() '? –

1

Следующий ответ может помочь вам: https://stackoverflow.com/a/8777776/3207406

  1. Вы можете иметь кортеж, содержащий все столбцы, которые могут быть использованы в какой-то момент
  2. создать список кортежей с фактическими значениями, которые вы хотите вставить , со значением по умолчанию DEFAULT,
  3. , а затем bulk-insert их

 Смежные вопросы

  • Нет связанных вопросов^_^