postgresql 将嵌套元组传递到psycopg3中的VALUES

tjvv9vkg  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(104)

我正在尝试将一些psycopg2代码更新到psycopg3。我尝试基于从Python传递的一组值进行选择(与现有表连接)。如果没有join,一个简单的例子是:

with connection.cursor() as cur:
    sql = "WITH sources (a,b,c) AS (VALUES %s) SELECT a,b+c FROM sources;"
    data = (('hi',2,0), ('ho',5,2))
    cur.execute(sql, (data,) )
    print(cur.fetchone());

字符串
我得到一个错误

ProgrammingError: syntax error at or near "'("(hi,2,0)","(ho,5,2)")'"
LINE 1: WITH sources (a,b,c) AS (VALUES '("(hi,2,0)","(ho,5,2)")') S...


psycopg2代码使用了extras.execute_values,这在psycopg3中不可用。
有没有一种方法可以使用psycopg3传递中间表的值?

yfwxisqw

yfwxisqw1#

有一种方法:

import psycopg

con = psycopg.connect("dbname=test host=localhost  user=postgres")

with con.cursor() as cur:
    rs = []
    sql = "SELECT %s, %s + %s"
    data = [('hi',2,0), ('ho',5,2)]
    cur.executemany(sql, data, returning=True )
    while True:
        rs.append(cur.fetchone())
        if not cur.nextset():
            break
    print(rs)

[('hi', 2), ('ho', 7)]

字符串
psycopg cursor classes
executemmany(.)
注记
使用通常的fetchone()、fetchall(),您将能够读取仅由执行的第一个查询返回的记录。为了读取以下查询的结果,您可以调用nextset()来移动到以下结果集。
executemmany(returning=True)的一个典型用例可能是插入一堆记录并检索插入的主键,这些主键取自PostgreSQL序列。为此,您可以执行一个查询,例如INSERT INTO table VALUES(...)RETURNING id。因为每个INSERT都保证插入一条记录,所以可以使用以下模式获得新id的列表:

cur.executemany(query, records)
ids = []
while True:
    ids.append(cur.fetchone()[0])
    if not cur.nextset():
        break


警告
更明确地说,fetchall()本身不会返回所有返回的值!必须使用nextset()迭代结果。

更新

data_combined = [y for x in data for y in x]

data_combined
['hi', 2, 0, 'ho', 5, 2]

qry = sql.Composed(
    [sql.SQL("select a, b + c from ( "), sql.SQL('VALUES '), 
     sql.SQL(",").join(
        sql.SQL("({})").format(sql.SQL(',').join(sql.Placeholder() 
        * len(data[0]))) * len(data)), 
     sql.SQL(") as t(a, b, c)")])

print(qry.as_string(con))
select a, b + c from ( VALUES (%s,%s,%s),(%s,%s,%s)) as t(a, b, c)

cur.execute(qry, data_combined)

cur.fetchall()
[('hi', 2), ('ho', 7)]


使用sql.Composed构建了一个带有可变数量的VALUES和占位符的查询。将元组的元组组合成一个平面列表并将其传递给查询。

相关问题