【问题标题】:How to add a key value pair in Json type column in Postgres如何在 Postgres 的 Json 类型列中添加键值对
【发布时间】:2020-09-08 07:43:46
【问题描述】:

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

现有状态:

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

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

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

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

【问题讨论】:

    标签: sql json postgresql sql-update


    【解决方案1】:

    首先,PG9.4 已经过时,甚至现在还没有完善。 PG9.5 包含 as 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 的 schema,你可以使用 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”:“In Progress”}'并转换回json:

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

    【讨论】:

      【解决方案2】:
      UPDATE table_name SET column_name = jsonb_set(cast(column_name as jsonb), '{key}', '"value"', true) WHERE id = 'target_id';
      

      如果它不存在,这将在json列中添加键值对,如果键存在,它将覆盖它的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-01
        • 2014-11-15
        • 2019-04-02
        相关资源
        最近更新 更多