postgresql:jsonb在一个查询中更新多个键
Posted
技术标签:
【中文标题】postgresql:jsonb在一个查询中更新多个键【英文标题】:postgresql: jsonb update multiple keys in one query 【发布时间】:2017-03-13 20:31:06 【问题描述】:我有以下 postgresql 行作为 JSONB 行:
age:26
我想替换它,使我看起来像这样:
age: 30, city: "new york city"
如何在 postgressql 中做到这一点?有人提到使用jsonb_set()
,但我没有看到任何在一个查询中更新多个键的示例。
【问题讨论】:
postgres jsonb_set multiple keys update 【参考方案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 时要记住四件事:
-
将第一个参数传递给 jsonb_set 函数是一个目标(您想替换的地方)
json 键
json 值
如果新列变为真
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数组。以上是关于postgresql:jsonb在一个查询中更新多个键的主要内容,如果未能解决你的问题,请参考以下文章
Django / PostgresQL jsonb (JSONField) - 将选择和更新转换为一个查询
使用 PostgreSQL 查询更新复杂 JSONB 对象以删除子子属性
如何逃脱? (问号)运算符在 Rails 中查询 Postgresql JSONB 类型