postgresql 如何使用psycopg2参数化多个元组,而不使用f字符串

chy5wohz  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(3)|浏览(112)

我想知道如何参数化以下postgres:

UPDATE your_table as t
SET val = x.val_to
FROM ( VALUES 
  (1, 20),
  (3, 44)
) as x (val_from, val_to)
WHERE t.val = x.val_from
AND
your_table.other_id = %(other_id_value)
;

字符串
其中(1, 20), (3, 44)将使用psycopg2进行参数化。
使用:

cur.execute("""
UPDATE your_table as t
SET val = x.val_to
FROM ( VALUES 
  $(vals)s
) as x (val_from, val_to)
WHERE t.val = x.val_from
AND
your_table.other_id = %(other_id_value)s
;
""", { 
    'other_id_value' : 3843,
    'vals' : [(1, 20), (3, 44)] 
}
)


不管用
在psycopg2 https://www.psycopg.org/docs/extras.html中,他们有:

>>> execute_values(cur,
... """UPDATE test SET v1 = data.v1 FROM (VALUES %s) AS data (id, v1)
... WHERE test.id = data.id""",
... [(1, 20), (4, 50)])


但是我还需要参数化data.id,而不仅仅是VALUES

axkjgtzd

axkjgtzd1#

我想你可以通过@jjanes execute_batch()来实现这一点。
我在评论中提到的JSON方法是:

with invars as (
  select (j->>0)::int as val_from, (j->>1)::int as val_to, %s as other_id
    from jsonb_array_elements((%s)::jsonb) as e(j)
)
update your_table as t
   set val = i.val_to
  from invars i
 where t.val = i.val_from
   and t.other_id = i.other_id

字符串
python的执行看起来像这样:

cur.execute(<above sql>, (other_id, json.dumps([(1, 20), (3, 44)]))

6psbrbz9

6psbrbz92#

psycopg2.extras为此提供了函数psycopg2.extras.execute_values。
考虑到需要包含另一个参数,我只需要用一个额外的成员来装饰元组,这个成员在所有元组中都是恒定的,这样就有了一个像AS data (id, v1, c1)这样的别名。

kpbpu008

kpbpu0083#

使用psycopg2sql模块。未对实际数据进行测试。

import psycopg2
from psycopg2 import sql
from psycopg2.extras import execute_values

other_id_value = 3843
vals = [(1, 20), (3, 44)] 

qry_sql = sql.SQL("""UPDATE your_table as t
SET val = x.val_to
FROM ( VALUES %) as x (val_from, val_to)
WHERE t.val = x.val_from
AND
your_table.other_id = {}""").format(sql.Literal(other_id_value))

cur.execute(qry_sql, vals)

字符串

相关问题