如何在Postgres的Json type列中添加键值对

时间:2020-09-08 07:43:46

标签: sql json postgresql sql-update

我在Postgres数据库(9.4.9)中有一个json类型的列(状态)。我想为状态的现有值添加新的键值对。示例:

现有状态:

"status": {
            "keysterStatus": "In Progress"
          }

添加键值对后,我希望它看起来像这样

"status": {
            "provisioningStatus": "In Progress",
            "keysterStatus": "In Progress"
          }

到目前为止,我一直在使用存储库save()方法来完成此操作,但这正在写入整行,并且在有多个请求的情况下,可能会进行并发读写。因此想摆脱save()方法并进行列级更新。

1 个答案:

答案 0 :(得分:0)

首先,PG9.4已过时,甚至没有被废弃。 PG9.5包含为json_set函数:

SELECT jsonb_set(status::jsonb,
                 '{provisioningStatus}',
                 to_jsonb('In Progress'))::jsonb
  FROM ....;

可以使用串联|| swith转换为jsonb并返回:

SELECT (status::jsonb || '{"provisioningStatus": "In Progress"}')::json
  FROM ....;

对于PG9.4,如果您知道json的架构,则uou可以使用json_populate_record / row_to_json:

SELECT (
         SELECT row_to_json(r)
           FROM (
                  SELECT r.*, 'In Progress' AS provisioningStatus
                    FROM json_populate_record(null::myrowtype, status) AS r
                ) AS r
       ) AS result
  FROM .... 

或者您可以使用json_each_text:

SELECT (
         SELECT json_object_agg(key, value)
           FROM (
                  SELECT *
                    FROM json_each_text(status)
                   UNION ALL
                  SELECT 'provisioningStatus', 'In Progress'
                ) AS a
        ) AS result
   FROM ... 

最后一个(但很丑)的方法可能只是将json转换为字符串,删除最后一个'}',添加“ provisioningStatus”:“进行中”}',然后转换回json:

SELECT (substr(status::text, 1, length(status::text) - 1)
          || ', "provisioningStatus": "In Progress"}')::json
  FROM ...