Выполнить значения Вам нужно будет переписать или привести выражение - PullRequest
0 голосов
/ 03 июня 2018

Я пытаюсь выполнить массовую вставку в таблицу со схемой

CREATE TABLE IF NOT EXISTS test (symbol VARCHAR(16), ts timestamp)

У меня есть массив значений для вставки в форме

[('AAPL',1528004700), ('AAPL', 1528005600)]

Мой запрос на вставку выглядит так, как показанониже

insert into test VALUES %s

и мой код Python для выполнения вставки выглядит как

psycopg2.extras.execute_values(cursor, insert_stmt, [('AAPL',1528004700), ('AAPL', 1528005600)])

Я получаю ошибку

ProgrammingError: column "ts" is of type timestamp without time zone but expression is of type integer
LINE 1: insert into test VALUES ('AAPL',1528004700),('AAPL',15280056...
                                        ^
HINT:  You will need to rewrite or cast the expression.

Я понимаю, что to_timestamp может решить эту проблемуоднако при вставке execute_values ​​не позволяет мне добавлять несколько заполнителей, и мне нужно выполнять массовые вставки каждый раз.Отметка времени не должна содержать часовой пояс.Как я могу исправить эту ошибку

Спасибо!

ОБНОВЛЕНИЕ 1

execute_batch () работает отлично, так как я могу добавить to_timestamp в разделе заполнителя

insert = "insert into test VALUES (%s, to_timestamp(%s))"

, за которым следует

psycopg2.extras.execute_batch(cur, insert, [('AAPL',1528004700), ('AAPL', 1528005600)])

Однако я хотел бы использовать execute_values, поскольку он немного быстрее, чем execute_batch ()

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

Я не уверен насчет psycopg2.extras.execute_values, но обычным способом является использование метода executemany для вставки списка записей

Оператор вставки записывается с %s для каждого столбца.В этом конкретном случае нам также необходимо привести целое число к временной метке.К счастью, postgresql предоставляет для этого функцию to_timestamp.

values = [('AAPL',1528004700), ('AAPL', 1528005600)]
stmt = 'insert into test values (%s, to_timestamp(%s))'
cur.executemany(stmt, values)
0 голосов
/ 03 июня 2018

Это должно работать:

from datetime import datetime
psycopg2.extras.execute_values(cursor, insert_stmt, [('AAPL',datetime.fromtimestamp(1528004700)), ('AAPL', datetime.fromtimestamp(1528005600))])

Редактировать: В общем, Postgres не может угадать, что ваш 1528004700 - это временная метка, вам нужно как-то явно ее указать.Ваше решение с to_timestamp помещает «это временная метка» на стороне Postgres, выше кода размещает его на стороне python.С информационной точки зрения они эквивалентны, я не проверял, какой из них более эффективен.

...