使用聚合函数更新json数组

时间:2015-02-20 04:39:48

标签: sql json postgresql python-2.7 psycopg2

使用Postgres 9.3,Python 2.7,psycopg2 我有一个名为SomeTable的表格,其中包含json字段some_json_arrayrow_id密钥。

some_json_array看起来像这样:

"[{'key': 'value_one'}, {'key': 'value_two'}, etc]"

我还有一个函数,我正在尝试将一些元素添加到与给定SomeTable对应的row_id的json数组中。

我的代码如下:

CREATE OR REPLACE FUNCTION add_elements (insertion_id smallint, new_elements_json json)
RETURNS void AS $$
BEGIN
    UPDATE SomeTable
    SET some_json_array = (SELECT array_to_json(array_agg(some_json_array) || array_agg(new_elements_json)))
    WHERE row_id = insertion_id;
END;
$$ LANGUAGE plpgsql;

我收到以下错误:

Cannot use aggregate function in UPDATE

我相信抱怨array_agg()

如何修改此功能才能使其正常工作?如有必要,我可以将WHERE语句粘贴到SELECT语句中。

1 个答案:

答案 0 :(得分:2)

聚合函数不能像普通函数一样使用,只能在聚合上下文中使用。

由于Postgres不能直接操作JSON数组(它只是一个有效的json 到Postgres,而不是数组),你必须...

  • json值转换为text,连接新元素,生成有效的JSON语法并转换回来,
  • 或转换为json json[]的Postgres数组,追加新元素并将此Postgres数组转换回json值。
    array_to_json()非常聪明,不能再次对Postgres数组的json元素进行编码。

第一种方法更容易出错。您必须手动构建有效的JSON。以下是第二个变体的实现:

CREATE OR REPLACE FUNCTION add_elements (_id int2, _elem json)
  RETURNS void AS
$func$
BEGIN
    UPDATE SomeTable s
    SET    some_json_array = array_to_json(ARRAY(
              SELECT * FROM json_array_elements(s.some_json_array)
              UNION  ALL SELECT _elem
              ))
    WHERE  s.row_id = _id;
END
$func$ LANGUAGE plpgsql;

函数包装器与问题无关。可能只是一个简单的SQL语句。

相关: