使用psycopg2更新JSONB



以下针对多模式PostgreSQL(v.12(DB的SQL语句是完全有效的,它达到了预期的结果。

我需要更新一个深度JSONB值,如下所示:

UPDATE schema."Some_table_name" SET jsonb_col = jsonb_set(jsonb_col, '{path,to,key}', '"string value"') WHERE id = 1;

当我尝试使用psycopg2从python执行上述操作时,我没有得到任何错误,但也没有更新。

def update_method(schema, path, value):
q = f"""UPDATE {schema}."Some_table_name" SET jsonb_col = jsonb_set(jsonb_col, '{path}', '{value}') WHERE id = 1"""
cur = conn.cursor()
cur.execute(q)
conn.commit()
cur.close()
update_method('schema_name', '{path,to,key}', '"string value"') 

我尝试将q语句中的路径具体转换为:'{path}'::text[]。仍然没有错误,也没有更新。

知道我如何使用psycopg2和上面的方法更新深度JSONB吗?

EDIT-在阅读了评论并尝试了@Abelisto的代码后,我意识到什么会起作用(我觉得有点傻(。以下代码正确更新任何深度JSONB值:

def update_method(connection, schema, path, value):
q = f"""UPDATE {schema}."Some_table_name" SET jsonb_col = jsonb_set(jsonb_col, '{path}', '{value}') WHERE id = 1"""
cur = connection.cursor()
cur.execute(q)
connection.commit()
cur.close()
update_method(conn, 'schema_name', '{path,to,key}', '"string value"') 

这实际上不是解决方案,但很难在注释中发布python代码。

这个问题肯定需要一些调试。IMO这个代码片段应该足以找到问题的来源:

#!/usr/bin/python3
import psycopg2
schema_name = 'pg_temp'
table_name = 'foo'
init_value = '{"a": "x", "b": {"c": "y"}}'
conn = psycopg2.connect('')
c = conn.cursor();
c.execute(f"""create table {schema_name}.{table_name}(id int, col jsonb)""")
c.execute(f"""insert into {schema_name}.{table_name} values(1, '{init_value}')""")
c.execute(f"""select * from {schema_name}.{table_name} where id = 1""")
print(c.fetchall())
def update_method(schema, path, value):
qs = f"""select * from {schema}.{table_name} where id = 1"""
q = f"""UPDATE {schema}.{table_name} SET col = jsonb_set(col, '{path}', '{value}') WHERE id = 1"""
cur = conn.cursor()
cur.execute(qs)
print(cur.fetchall())
print(q)
cur.execute(q)
cur.execute(qs)
print(cur.fetchall())
conn.commit()
cur.close()
update_method(schema_name, '{b,c}', '"string value"') 

输出:

[(1, {'a': 'x', 'b': {'c': 'y'}})]
[(1, {'a': 'x', 'b': {'c': 'y'}})]
UPDATE pg_temp.foo SET col = jsonb_set(col, '{b,c}', '"string value"') WHERE id = 1
[(1, {'a': 'x', 'b': {'c': 'string value'}})]

正如您所看到的,为这个简单的测试用例工作的代码。

最新更新