postgresql:jsonb在一个查询中更新多个键

时间:2016-10-31 17:43:19

标签: sql postgresql psycopg2 jsonb

我将以下postgresql行作为JSONB行:

{age:26}

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

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

如何在postgressql中执行此操作?有人提到使用jsonb_set(),但我还没有看到在一个查询中更新多个密钥的任何示例。

5 个答案:

答案 0 :(得分:14)

在jsonb_set()

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

尽管您可以嵌套 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 抽象不太规范

答案 3 :(得分:0)

使用 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')

答案 4 :(得分:-1)

在更新数据的同时,您可以使用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;