铸造JSON来HSTORE Postgres里9.3+?

问题描述 投票:4回答:2

我读过的文档,并似乎有执行ALTER TABLE ... ALTER COLUMN ... USING语句来json类型列直接转换为hstore类型没有明显的方式。有没有可用的功能(即我所知道的)来执行转换。

我有一个最好的方法是创建类型hstore的新列,我的JSON数据复制到使用一些外部工具,新列,删除旧json列,并重新命名新hstore列老列的名称。

有没有更好的办法?

我至今是:

$ CREATE TABLE blah (unstructured_data JSON);

$ ALTER TABLE blah ALTER COLUMN unstructured_data 
       TYPE hstore USING CAST(unstructured_data AS hstore);
ERROR:   cannot cast type json to hstore
json postgresql database-migration hstore
2个回答
10
投票

不幸的是,PostgreSQL并不让各类USINGALTER TABLE ... SET DATA TYPE ...子句中的表达式(f.ex.子查询是不允许的)。

但是,你可以写克服这个功能,你只需要决定如何处理先进的类型做(在对象的值),如数组和对象。下面是一个例子,它只是将它们转换成字符串:

CREATE OR REPLACE FUNCTION my_json_to_hstore(json)
  RETURNS hstore
  IMMUTABLE
  STRICT
  LANGUAGE sql
AS $func$
  SELECT hstore(array_agg(key), array_agg(value))
  FROM   json_each_text($1)
$func$;

在这之后,你可以在你的ALTER TABLE使用,如:

ALTER TABLE blah
  ALTER COLUMN unstructured_data
  SET DATA TYPE hstore USING my_json_to_hstore(unstructured_data);

1
投票

有“陷阱”重复键 - (!)双方jsonhstore输入允许的,但不幸的是解决不同。考虑这个例子值:

json '{"double_key":"key1","foo":null,"double_key":"key2"}'

json,“double_key实际上是 'KEY2'。 The manual:

因为json类型存储输入文本的精确副本,它将保留JSON对象中键的顺序标记之间语义无关紧要的空格,以及。此外,如果该值内的JSON对象包含相同的键不止一次,所有的键/值对被保留。 (处理功能考虑的最后一个值作为操作之一。)

大胆重点煤矿。

hstore,然而,键/值对的顺序相同,“double_key”可能有效地将“KEY1”。 The manual:

hstore每个键都是唯一的。如果声明hstore有重复键,只有一个会被存储在hstore并没有保证哪个将被保留:

通常情况下,一个关键的第一个实例,但是这是一个实现细节可能会改变。

一个简单,快速的选择始终保持有效,手术值:铸转换之前jsonbThe manual again:

[...] jsonb不保留空白,不保留对象键的顺序,并不会保留重复的对象键。如果输入指定重复键,只有最后一个值保持。

修改@pozs's conversion function

CREATE OR REPLACE FUNCTION json2hstore(json)
  RETURNS hstore AS
$func$
  SELECT hstore(array_agg(key), array_agg(value))
  FROM   jsonb_each_text($1::jsonb)  -- !
$func$ LANGUAGE sql IMMUTABLE STRICT;

需要的Postgres 9.4或更高版本。 Postgres的9.3有json类型,但不jsonb,但。无操作在PL / V8可能是替代那里,就像@jpmc mentioned

© www.soinside.com 2019 - 2024. All rights reserved.