【问题标题】:postgresql: jsonb update multiple keys in one querypostgresql:jsonb在一个查询中更新多个键
【发布时间】:2017-03-13 20:31:06
【问题描述】:

我有以下 postgresql 行作为 JSONB 行:

{age:26}

我想替换它,使我看起来像这样:

{age: 30, city: "new york city"}

如何在 postgressql 中做到这一点?有人提到使用jsonb_set(),但我没有看到任何在一个查询中更新多个键的示例。

【问题讨论】:

标签: sql postgresql psycopg2 jsonb


【解决方案1】:

使用 sqlalchemy:

from sqlalchemy import func, and_, any_, cast
from sqlalchemy.dialects.postgresql import JSONB


db.session.query(Model).filter(
    Model.id == any_(ids)
).update({
    Model.your_jsonb_field: cast(
        Model.your_jsonb_field,
        JSONB,
    ).concat(
        func.jsonb_build_object('key1', 'value1'),
    ).concat(
        func.jsonb_build_object('key2', 'value2'),
    )
}, synchronize_session='fetch')

【讨论】:

    【解决方案2】:

    Postgresql 很棒。也可以使用string concatenation operator||

    UPDATE wooden_table
    SET doc = doc
        || '{"color" : "red"}' 
        || '{"hardness" : "1H"}';
    

    此方法也适用于值端内的 JSON 值。

    【讨论】:

      【解决方案3】:

      虽然你可以只嵌套 jsonb_set 动作,但阅读起来会变得非常糟糕。

      相反,您可以使用jsonb_object

      SET my_column = my_column || jsonb_object(
          array[ -- keys
              'age',
              'city',
              'visits'
          ],
          array[ -- values
              31::text,
              'Johannesburg'::text,
              ((my_column#>>'{visits}')::int + 1)::text -- increment
          ]
      )
      

      注意:您将失去类型安全性,因为它仅处理文本字段,但您可以进行部分更新(仅添加您想要更新的字段),如果您从另一种语言处理它,它往往是非常可编程的,如果您SQL 抽象不太规范

      【讨论】:

      • 这对于文本值非常有用,但它不适用于 json 值。
      • 是的,你失去了类型安全。但即使有柜台,我也发现这是一个小小的不便。这使我可以使用一列来动态添加新的可变统计信息,而无需更新架构。
      【解决方案4】:

      在更新数据时,您可以使用 jsonb 列,还可以根据您拥有的属性创建 json 格式数据,在执行 jsonb 时要记住四件事:

      1. 将第一个参数传递给 jsonb_set 函数是一个目标(您想替换的地方)
      2. json
      3. json
      4. 如果新列变为真
      select jsonb_set(jsonb_set('{}'::jsonb,'{age}','30',true)::jsonb,'{city}',to_jsonb('hyd'::text),true)::jsonb;
      

      【讨论】:

        【解决方案5】:

        在 jsonb_set() 中使用 jsonb_set()

        jsonb_set(jsonb_set('{age:26}'::jsonb,'{age}','"30"'::jsonb)::jsonb,'{city}','"new york city"'::jsonb)
        

        【讨论】:

        • 答案here 中所述的更新多个键的标准方法没有帮助,而这个答案非常适合我的情况,因为我需要更新多个键,其中一个是正常值,另一个是正常值是一个jsonb数组。
        猜你喜欢
        • 2021-01-15
        • 2022-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多