【问题标题】:Update JSONB using psycopg2使用 psycopg2 更新 JSONB
【发布时间】:2021-02-28 15:31:05
【问题描述】:

以下针对多模式 PostgreSQL (v.12) 数据库的 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 吗?

编辑 - 在阅读了 cmets 并尝试了 @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代码中的jsonb_set还是只是输入错误?
  • @Abelisto,只是打错了。
  • 对我有用(尽管它可能会受到 SQL 注入攻击)。也许给定的路径实际上并不存在于指示的行中,因此更新不会进行任何可见的更改。
  • 对我来说,为什么全局变量不起作用但将它用作它起作用的函数参数对我来说是个谜。请发布关于第一个和第二个代码 sn-ps 的答案以及为什么第一个失败而第二个成功。

标签: python postgresql psycopg2 jsonb


【解决方案1】:

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

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

#!/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'}})]

如您所见,代码适用于这个简单的测试用例。

【讨论】:

    猜你喜欢
    • 2014-10-05
    • 2023-02-03
    • 1970-01-01
    • 2017-08-23
    • 2016-08-05
    • 1970-01-01
    • 2021-12-31
    • 2018-03-22
    相关资源
    最近更新 更多