【问题标题】:Altering JSON column to INTEGER[] ARRAY将 JSON 列更改为 INTEGER[] ARRAY
【发布时间】:2014-02-24 19:12:46
【问题描述】:

我有一个包含整数数组的 JSON 列。我正在尝试将其转换为 INTEGER[] 列,但遇到了转换错误。

这是我的最终修改版本:

ALTER TABLE namespace_list ALTER COLUMN namespace_ids TYPE INTEGER[] USING string_to_array(namespace_ids::integer[], ',');

但是,这会引发以下错误: ERROR: cannot cast type json to integer[]

有什么想法可以解决这种转换吗?我已经尝试了几件事,但我最终遇到了同样的错误。好像去 json --> string --> --> array 不起作用。我有哪些选择?

编辑:

表定义:

db => \d+ namespace_list;

Column         |   Type   |  Table "kiwi.namespace_list" Modifiers|
---------------+----------+--------------------------------------+
id             | integer  | not null default nextval('namespace_list_id_seq'::regclass)
namespace_ids  | json     | not null default '[]'::json

样本数据:

id | namespace_ids | 
-------------------+
1 | [1,2,3]        |

【问题讨论】:

  • 提供一个表定义和一些示例值是礼貌的做法..
  • @ErwinBrandstetter 表定义已添加;几乎描述的内容(JSON 列)和示例数据。

标签: sql arrays json postgresql


【解决方案1】:

假设您的数组中没有无效字符。

在 Postgres 9.4 或更高版本中使用此处概述的转换函数:

CREATE OR REPLACE FUNCTION json_arr2int_arr(_js json)
  RETURNS int[] LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
'SELECT ARRAY(SELECT json_array_elements_text(_js)::int)';

ALTER TABLE namespace_list
  ALTER COLUMN namespace_ids DROP DEFAULT
, ALTER COLUMN namespace_ids TYPE int[] USING json_arr2int_arr(namespace_ids);

db小提琴here


对于 Postgres 9.3 或更早版本:

ALTER TABLE namespace_list
ALTER COLUMN namespace_ids TYPE INTEGER[]
      USING translate(namespace_ids::text, '[]','{}')::int[];

具体的困难是你不能在USING 子句中包含子查询表达式,所以取消嵌套和重新聚合不是一种选择

SELECT ARRAY(SELECT(json_array_elements(json_col)::text::int))
FROM   namespace_list;

因此,我求助于字符串操作来为整数数组生成一个有效的字符串常量并将其强制转换。

DEFAULT

如果在稍后添加的实际表定义中存在像DEFAULT '[]'::json 这样的默认列,请在执行上述操作之前将其删除。 如果需要,您可以在之后添加一个新的DEFAULT。最好在同一事务(甚至命令)中:

ALTER TABLE namespace_list
   ALTER COLUMN namespace_ids DROP DEFAULT
,  ALTER COLUMN namespace_ids TYPE INT[] USING translate(namespace_ids::text, '[]','{}')::int[]
,  ALTER COLUMN namespace_ids SET DEFAULT '{}';

db小提琴here
sqlfiddle

【讨论】:

  • 我仍然收到ERROR: default for column "namespace_ids" cannot be cast automatically to type integer[]。任何想法为什么?
  • @Nayefc:去显示表定义的重要性。我在答案中添加了一些内容。
  • 这行得通,谢谢!我猜 '[]'::json 不能用这种方式转换成数组?有什么原因吗?
  • @Nayefc: 可以用同样的方式强制转换,但默认子句是表定义的一部分,这完全是另一回事。
猜你喜欢
  • 2018-11-03
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 2014-11-23
相关资源
最近更新 更多