Postgresql 更新 JSON 列保留一些键值并将附加键值添加为空
Posted
技术标签:
【中文标题】Postgresql 更新 JSON 列保留一些键值并将附加键值添加为空【英文标题】:Postgresql Update JSON Column Retaining Some KeyValues and Adding Additional KeyValue as null 【发布时间】:2016-09-06 15:51:03 【问题描述】:我正在尝试将metadata
JSONB 列用于多租户应用程序。每个租户的每个user
必须具有相同的metadata
,但租户具有不同的metadata
字段。
为了使每个租户的所有用户元数据保持同步,当租户管理员修改元数据字段时,我需要确保所有用户的元数据 JSONB 列都按照以下条件更新:
-
如果元数据字段/键已经存在,则需要保留该值
如果元数据字段/键是新的,则键需要添加空值
如果有任何元数据字段/键未包含在更新列表中,则应从 JSON 对象中删除它们
例如,租户 #1 的所有用户都分配了以下元数据: "EmployeeNo" : 123, "HireDate" : "2012-10-10", "Age" : 43
并且管理员决定他们不关心年龄,但他们确实想开始跟踪 ParkingSpace。
我需要新的元数据记录来保留 EmployeeNo 和 HireDate 值,删除 Age 键/值,并添加具有空值的 ParkingSpace 键。 "EmployeeNo" : 123, "HireDate" : "2012-10-10", "ParkingSpace" : null
.
我原以为我可以运行类似于以下内容的更新查询,它返回一个 JSONB 对象,如果键存在则选择值,如果键不存在则选择 null:
UPDATE users SET metadata = metadata[keys: 'EmployeeNo', 'HireDate', 'ParkingSpace'] WHERE tenant_id = 1;
显然这不起作用,但希望它表明问题所在?
【问题讨论】:
【参考方案1】:更新:我可能误解了你的问题。也许你想要这样的东西:
UPDATE users
SET metadata = (SELECT json_object_agg(n,metadata->>n) FROM unnest(ARRAY['EmployeeNo','HireDate','ParkingSpace']) AS t(n))
此解决方案涉及通过仅从原始 metadata
中提取您想要的字段来创建一个全新的 jsonb 对象。要复制的字段被指定为您可以轻松自定义的数组。
原答案:我认为应该这样做:
UPDATE users
SET metadata = (metadata - 'Age') || '"ParkingSpace": null'::jsonb;
我正在使用 ||
运算符将 2 个 jsonb 对象合并为一个,而 -
运算符用于删除键/值对。
【讨论】:
我可能会完成这项工作,理想情况下我不想跟踪被删除的列(在本例中为“年龄”)。 我重读了你的问题并更新了我的答案。让我知道这是否有效。 甜蜜,您更新的答案似乎完美无缺!现在我将不得不查看有关 why 的文档(尤其是 json_object_agg 和 unnest 数组)。谢谢!以上是关于Postgresql 更新 JSON 列保留一些键值并将附加键值添加为空的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL:具有选择性列的 row_to_json [重复]
使用 jooq/postgresql 从 json 中提取键/值对 - java
PostgreSql INSERT 插入数据判断数据是否存在,存在则更新,不存在则插入