使用 postgres 9.4 将 JSON 元素附加到数组

Posted

技术标签:

【中文标题】使用 postgres 9.4 将 JSON 元素附加到数组【英文标题】:Append JSON element to array using postgres 9.4 【发布时间】:2017-02-06 18:25:35 【问题描述】:

我正在尝试将 JSON 元素附加到我的数据库中已经存在的数组中。我知道 jsonb_set 但是我无法升级到 Postgres 9.4,因为这是一个 groovy 项目,Maven 上的最新 postgresql 版本是 9.4。

我目前有一个这样的json结构:

"playersContainer": 
        "players": [
            
                "id": "1",
                "name": "Nick Pocock",
                "teamName": "Shire Soldiers",
                "bio" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla imperdiet lorem tellus, in bibendum sem dignissim sed. Etiam eu elit sit amet lacus accumsan blandit sed ut dolor. Mauris vel dui non nisi vestibulum commodo vel id magna. Donec egestas magna in tincidunt mollis. Fusce mauris arcu, rhoncus ut lacus sed, fermentum ultrices elit. In sollicitudin at ex dapibus vestibulum. Pellentesque congue, est id lobortis viverra, mauris lectus pharetra orci, ut suscipit nisl purus vehicula est. Aliquam suscipit non velit vel feugiat. Quisque nec dictum augue.",
                "ratings": [
                    1,
                    5,
                    6,
                    9
                ],
                "assists": 17,
                "manOfTheMatches": 20,
                "cleanSheets": 1,
                "data": [
                    3,
                    2,
                    3,
                    5,
                    6
                ],
                "totalGoals": 19

            

我想将新玩家添加到玩家数组并更新我的数据库,我尝试进行更新,但它擦除了其余数据。有没有办法定位玩家数组并将新的 json 对象附加到它?

【问题讨论】:

Appending (pushing) and removing from a JSON array in PostgreSQL 9.2, 9.3, and 9.4?的可能重复 append a json object to an array within my postgres table的可能重复 【参考方案1】:

很遗憾 9.4 没有 json_set 功能。你可以使用这样的东西:

WITH old_players AS (
       SELECT $1 AS j
  ), new_player AS (
       SELECT $2 AS j
  ), all_players AS (
       SELECT json_array_elements(j->'playersContainer'->'players') AS p
         FROM old_players
        UNION ALL
       SELECT *
         FROM new_player
  )      SELECT ('"playersContainer": "players": ' || json_agg(p) || '')::json
    FROM all_players
;

您可以将其用作函数:

CREATE OR REPLACE FUNCTION add_player(old_player json, new_player json) RETURNS json AS $$
WITH all_players AS (
       SELECT json_array_elements(($1)->'playersContainer'->'players') AS p
        UNION ALL
       SELECT $2
  ) 
  SELECT ('"playersContainer": "players": ' || json_agg(p) || '')::json
    FROM all_players
$$ LANGUAGE sql IMMUTABLE;

然后你就可以调用它了:

UPDATE site_content SET content = add_player(content, '"id": "2",  "name": "Someone Else"') where id = :id;

【讨论】:

我正在尝试使用 array_append 但没有运气,我收到任何错误说它不存在,即使我使用的是 9.4 我尝试使用 -> 表示法获取我的玩家数组,然后附加我的新JSON,像这样 sql.executeUpdate(""" UPDATE site_content SET content = array_append(content->'playersContainer'->'players', '$json'); where id = :id """, id: player .teamId) array_append 不是 json 函数 (postgresql.org/docs/9.5/static/functions-json.html) w3resource.com/PostgreSQL/postgresql_array_append-function.php 9.4也没有json_agg。

以上是关于使用 postgres 9.4 将 JSON 元素附加到数组的主要内容,如果未能解决你的问题,请参考以下文章

在 Postgres JSON 数组中查询

在较旧的 Postgres (9.4) 上使用 Django 3+

如何从 Postgres 9.4 中转储大对象数据,然后将其导入 Postgres8.x?

postgres 9.4将多个分隔符上的列拆分为新列

在 postgres 9.4 中使用触发器执行外部程序

如何安装/更新到 Postgres 9.4?