【发布时间】:2021-06-01 16:37:39
【问题描述】:
我在 postgres 中有这张表
CREATE TABLE target (
a json
b integer
c text []
id integer
CONSTRAINT id_fkey FOREIGN KEY (id)
REFERENCES public.other_table(id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
)
我想使用 psycopg2 向其中插入数据
import psycopg2
import psycopg2.extras as extras
# data is of the form dict, integer, list(string), string <- used to get fkey id
data = [[extras.Json([{'a':1,'b':2}, {'d':3,'e':2}]), 1, ['hello', 'world'], 'ident1'],
[extras.Json([{'a':4,'b':3}, {'d':1,'e':9}]), 5, ['hello2', 'world2'], 'ident2']]
# convert data to list of tuples containing objects
x = [tuple(u) for u in data]
# insert data to the database
query = ('WITH ins (a, b, c, ident) AS '
'(VALUES %s) '
'INSERT INTO target (a, b, c, id) '
'SELECT '
'ins.a '
'ins.b '
'ins.c '
'other_table.id'
'FROM '
'ins '
'LEFT JOIN other_table ON ins.ident = other_table.ident;')
cursor = conn.cursor()
extras.execute_values(cursor, query, x)
当我运行它时,我得到了error: column "a" is of type json but expression is of type text。我试图通过在 SELECT 语句中添加类型转换来解决这个问题,但后来我得到了同样的错误 c 和 b。
最初我认为问题在于 WITH 语句,但根据我之前问题的答案,这似乎不是Postgres `WITH ins AS ...` casting everything as text
似乎execute_values 将所有值作为带有' ' 的文本发送。
主要问题:我怎样才能让execute_values 根据它们的 python 数据类型而不是文本来发送值?
子问题:
如何确认 execute_values 实际上是以带引号的文本形式发送值?execute_values https://www.psycopg.org/docs/extras.html 的模板参数的目的是什么,有帮助吗?
【问题讨论】:
-
这个:
x = [tuple(u) for u in data]没必要。(VALUES %s)将输入收集为文本,因为没有指定类型。您将需要CAST每个SELECT出现的正确类型。 -
@AdrianKlaver 你说没有指定类型,我该如何指定类型?
标签: postgresql psycopg2