【发布时间】:2021-08-19 18:02:27
【问题描述】:
我在 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, data)
当我按原样运行时,出现错误:column "a" is of type json but expression is of type text
我试图通过在 SELECT 语句中添加类型转换来解决这个问题
'SELECT '
'ins.a::json '
'ins.b '
'ins.c '
'other_table.id'
然后我收到错误column "c" is of type text[] but expression is of type text
所以我以同样的方式解决了这个问题:
'SELECT '
'ins.a::json '
'ins.b '
'ins.c::text[]'
'other_table.id'
所以现在我收到了错误column "b" is of type integer but expression is of type text
这个例子有些简化,因为我在原始查询中有更多列。
-
WITH ins ...语句是否总是将所有内容都转换为文本?这对我来说似乎是一种奇怪的行为 - 有没有一种无需手动对每一列进行类型转换的方法来编写代码?这似乎不优雅且计算效率低下的数据被转换,例如。从 python int 到 postgres 文本到 postgres 整数。
【问题讨论】:
-
正如@Jim Jones 指出的那样,问题不在于该问题所假设的 WITH 语句。因此,我在这里重新提出了问题stackoverflow.com/questions/67792770/…
标签: python sql postgresql psycopg2