2017-02-02 13 views
1

Я пытаюсь вставить большое количество строк в Postgres, используя cursor.mogrify используя эти данные psycopg2: insert multiple rows with one queryВставка строк в БД из списка кортежей с помощью cursor.mogrify дает ошибка

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

cursor = conn.cursor() 

    args_str = ','.join(cursor.mogrify("(%s,%s,%s,%s,%s,%s,%s,%s)", x) for x in data) 

    cursor.execute(
     "insert into table1 (n, p, r, c, date, p1, a, id) values " + args_str)` 

но получаю ошибку:

TypeError: sequence item 0: expected str instance, bytes found 

в строке:.

args_str = ','.join(cursor.mogrify("(%s,%s,%s,%s,%s,%s,%s,%s)", x) for x in data) 

Если я пытаюсь изменить к б '' присоединиться (cursor.mogrify ("(% s, % s,% s,% s,% s,% s,% s,% s) ", x) для x в данных), затем выполнить запрос дает ошибку для вставки байта ....

Я что-то не так?

+0

Для вставки большого количества строк может быть полезно использовать копию. –

+0

@RomanTkachuk Согласитесь, что COPY во много раз быстрее этого .., но иногда запись в файл не является вариантом или даже если иногда копировать файл на сервер нет. – MANU

+1

Вы можете КОПИРОВАТЬ ОТ STDIN. Без записи в файл. –

ответ

1
data = [(1,2),(3,4)] 
args_str = ','.join(['%s'] * len(data)) 
sql = "insert into t (a, b) values {}".format(args_str) 
print (cursor.mogrify(sql, data).decode('utf8')) 
#cursor.execute(sql, data) 

Выход:

insert into t (a, b) values (1, 2),(3, 4) 
0

Вы можете сделать что-то подобное, но проверьте значения dict, чтобы предотвратить инъекцию sql.

>>> from psycopg2.extensions import AsIs 
>>> _insert_sql = 'INSERT INTO myTable (%s) VALUES %s RETURNING id'  
>>> data = {"col_1": "val1", "col_2": "val2"} 
>>> values = (AsIs(','.join(data.keys())), tuple(data.values())) 
>>> print(cur.mogrify(_insert_sql, values)) 
b"INSERT INTO myTable (col_1,col_2) VALUES ('val1', 'val2') RETURNING id"