Вставить список Python в базу данных Postgres - PullRequest
3 голосов
/ 14 октября 2011

У меня проблемы с форматированием списка для вставки с помощью psycopg.Вот пример кода, который я пытаюсь сделать.В основном я просто читаю данные из одной таблицы и пытаюсь вставить их в другую таблицу.

Код:

cur.execute("""select data from \"Table1\" where lat=-20.004189 and lon=-63.848004""")
rows = cur.fetchall()
print rows
cur.execute("""INSERT INTO \"%s\" (data) VALUES (ARRAY%s)""" % (args.tableName,rows)))

Результат, возвращаемый первым запросом выбора, выглядит следующим образом:

[([6193, 3975, 4960, 5286, 3380, 970, 3328, 3173, 2897, 2457, 2443, 2674, 2172, 2740, 3738, 4907, 3691, 4234, 3651, 3215],)]

Когда я пытаюсь вставить это в другую таблицу, я получаю следующую ошибку формата.

   cur.execute(cur.mogrify("""INSERT INTO \"%s\" (data) VALUES (%s)""" % (args.tableName,rows)))
psycopg2.ProgrammingError: syntax error at or near "["
LINE 1: INSERT INTO "DUMMY1km" (data) VALUES ([([6193, 3975, 4960, 5...

Я попытался cur.mogrify, но, похоже, это не помогает.

Пожалуйста, дайте мне знать, если у кого-нибудь есть решение этой проблемы.

Спасибо, Adi

1 Ответ

5 голосов
/ 14 октября 2011

Я не думаю, что mogrify нужен здесь.Используйте executemany и передайте rows в качестве второго аргумента.

cur.executemany(
    """INSERT INTO "%s" (data) VALUES (%%s)""" % (args.tableName),rows)

Использование параметризованных аргументов помогает предотвратить SQL-инъекцию .

Имя таблицы не может быть параметризованопоэтому мы должны использовать интерполяцию строк, чтобы поместить имя таблицы в запрос SQL.%%s получает экранированный знак процента и становится %s после интерполяции строки.


Кстати, (поскольку a_horse_with_no_name уже указал ), вы можете использовать * INSERT INTO ... ВЫБРАТЬ форму из INSERT, чтобы выполнить оба SQL-запроса как один:

cur.execute(
    """INSERT INTO %s (data)
       SELECT data FROM Table1
       WHERE lat=-20.004189 AND lon=-63.848004""" % (args.tableName))

В соответствии с вопросом в комментариях, если имеется несколько полей, тоSQL становится:

cur.executemany(
    """INSERT INTO {t} (lat,lon,data1,data2) 
       VALUES (%s,%s,%s,%s)""".format(t=args.tableName),rows)

(Если вы используете метод format, вам не нужно экранировать все остальные %s s.)

...