Postgresql 更新 JSON 列保留一些键值并将附加键值添加为 null
Postgresql Update JSON Column Retaining Some KeyValues and Adding Additional KeyValue as null
我正在尝试将 metadata
JSONB 列用于多租户应用程序。每个租户的每个 user
必须具有相同的 metadata
,但租户具有不同的 metadata
字段。
为了使每个租户的所有用户元数据保持同步,当租户管理员修改元数据字段时,我需要确保所有用户的元数据 JSONB 列更新为以下标准:
- 如果元数据field/key已经存在,需要保留该值
- 如果元数据field/key是新的,key需要添加一个空值
- 如果有任何元数据 fields/keys 未包含在更新列表中,应将其从 JSON 对象中删除
例如,租户 #1 的所有用户都分配了以下元数据:{ "EmployeeNo" : 123, "HireDate" : "2012-10-10", "Age" : 43 }
并且在某处管理员决定他们不关心年龄,但他们确实想开始跟踪 ParkingSpace .
我需要新的元数据记录来保留 EmployeeNo 和 HireDate 值,删除 Age key/value,并添加具有空值的 ParkingSpace 键。 { "EmployeeNo" : 123, "HireDate" : "2012-10-10", "ParkingSpace" : null }
.
我原以为我可以 运行 一个类似于下面的更新查询,它 returns 一个 JSONB 对象,如果键存在,它会选择值,并且如果没有则为 null:
UPDATE users SET metadata = metadata[keys: 'EmployeeNo', 'HireDate', 'ParkingSpace'] WHERE tenant_id = 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 对象合并为一个的 ||
运算符和删除 key/value 对的 -
运算符。
我正在尝试将 metadata
JSONB 列用于多租户应用程序。每个租户的每个 user
必须具有相同的 metadata
,但租户具有不同的 metadata
字段。
为了使每个租户的所有用户元数据保持同步,当租户管理员修改元数据字段时,我需要确保所有用户的元数据 JSONB 列更新为以下标准:
- 如果元数据field/key已经存在,需要保留该值
- 如果元数据field/key是新的,key需要添加一个空值
- 如果有任何元数据 fields/keys 未包含在更新列表中,应将其从 JSON 对象中删除
例如,租户 #1 的所有用户都分配了以下元数据:{ "EmployeeNo" : 123, "HireDate" : "2012-10-10", "Age" : 43 }
并且在某处管理员决定他们不关心年龄,但他们确实想开始跟踪 ParkingSpace .
我需要新的元数据记录来保留 EmployeeNo 和 HireDate 值,删除 Age key/value,并添加具有空值的 ParkingSpace 键。 { "EmployeeNo" : 123, "HireDate" : "2012-10-10", "ParkingSpace" : null }
.
我原以为我可以 运行 一个类似于下面的更新查询,它 returns 一个 JSONB 对象,如果键存在,它会选择值,并且如果没有则为 null:
UPDATE users SET metadata = metadata[keys: 'EmployeeNo', 'HireDate', 'ParkingSpace'] WHERE tenant_id = 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 对象合并为一个的 ||
运算符和删除 key/value 对的 -
运算符。