在psycopg2中使用带有jsonb函数的预准备参数

时间:2016-03-15 12:03:00

标签: postgresql psycopg2

我有这个原始的Postgres声明

UPDATE objects 
SET property=jsonb_set(property, '{path1,static}', '["a", "b", "c"]')
WHERE id = 1;

对应于db

中的此JSONB对象
{
  "property": {
    "path1": {"static": ["foo"]},
    "path2": {"static": ["bar"]}
  }
}

问题是我使用psycopg2来执行此语句,并希望动态构建路径,以便我可以设置所有path1, path2, path3, ...。显然我可以这样写它

 def update(uid, path_key, values):
    """
    :params: int     path_key could be 1,2,3
    :params: list    values could be ["a", "b", "c"]
    """
    path = '{path{}, static}'.format(path_key)
    values = json.dumps(values)
    cursor.execute("UPDATE objects SET property=jsonb_set(property, %s, %s) WHERE id=%s;", [path, values, uid]

这有效,但我想知道是否有办法利用预备语句来完成它而不必自己手动构建路径或值,例如。

cursor.execute("""UPDATE objects
                  SET property=jsonb_set(property, '{%s,static}', %s) 
                  WHERE id=%s;""", [path, ("a", "b", "c"), uid])

1 个答案:

答案 0 :(得分:0)

不确定我理解。如果要在单个命令中执行所有更新,则这是SQL语法:

update objects 
set  property = jsonb_set(property, path, values)
from (values
    (1, '{property,path1,static}'::text[], '["a", "b", "c"]'::jsonb),
    (1, '{property,path2,static}', '["x", "y", "z"]'),
    (2, '{property,path1,static}', '["h", "i", "j"]')
) s (id, path, values)
where objects.id = s.id

如果上述符合要求,也可以简化Psycopg参数传递。