【发布时间】:2017-03-13 20:31:06
【问题描述】:
我有以下 postgresql 行作为 JSONB 行:
{age:26}
我想替换它,使我看起来像这样:
{age: 30, city: "new york city"}
如何在 postgressql 中做到这一点?有人提到使用jsonb_set(),但我没有看到任何在一个查询中更新多个键的示例。
【问题讨论】:
标签: sql postgresql psycopg2 jsonb
我有以下 postgresql 行作为 JSONB 行:
{age:26}
我想替换它,使我看起来像这样:
{age: 30, city: "new york city"}
如何在 postgressql 中做到这一点?有人提到使用jsonb_set(),但我没有看到任何在一个查询中更新多个键的示例。
【问题讨论】:
标签: sql postgresql psycopg2 jsonb
使用 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')
【讨论】:
Postgresql 很棒。也可以使用string concatenation operator、||
UPDATE wooden_table
SET doc = doc
|| '{"color" : "red"}'
|| '{"hardness" : "1H"}';
此方法也适用于值端内的 JSON 值。
【讨论】:
虽然你可以只嵌套 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 抽象不太规范
【讨论】:
在更新数据时,您可以使用 jsonb 列,还可以根据您拥有的属性创建 json 格式数据,在执行 jsonb 时要记住四件事:
select jsonb_set(jsonb_set('{}'::jsonb,'{age}','30',true)::jsonb,'{city}',to_jsonb('hyd'::text),true)::jsonb;
【讨论】:
在 jsonb_set() 中使用 jsonb_set()
jsonb_set(jsonb_set('{age:26}'::jsonb,'{age}','"30"'::jsonb)::jsonb,'{city}','"new york city"'::jsonb)
【讨论】: