如何将 hstore[] 列转换为 jsonb?

How can I convert an hstore[] column to jsonb?

我有一个 hstore[] 列,我想将其转换为 jsonb,但我似乎无法在这两种类型之间转换。 (我 可以 从普通 hstore 投射没有问题)。

例如,如果单元格中有 '{foo=>bar,baz=>quux}'::hstore[],我希望将其转换为 '[{"foo":"bar","baz":"quux"}]'::jsonb

这在 postgresql 中如何实现?

通常,您可以使用 ALTER TABLE ... ALTER COLUMN ... TYPEUSING 子句进行具有额外逻辑的转换(或用于类型之间没有显式转换的转换)。

SELECT转换值的表达式是:

select (select json_agg(hstore_to_json(h)) from unnest(hstore_array) h)::jsonb
from   table_name

(或者,您可以使用 hstore_to_json_loose(h) 来获取数字和布尔值,而不是总是获取字符串。)

遗憾的是,您不能在此 USING 子句中使用子选择,因此您可以:

  1. 创建一个临时函数并在 USING

    中使用它
    create function temp_hstore_array_to_jsonb(hstore[])
      returns jsonb
      language sql
      immutable
    as $func$
      select json_agg(hstore_to_json(h))::jsonb
      from   unnest() h
    $func$;
    
    alter table table_name
      alter column hstore_array
      type jsonb
      using temp_hstore_array_to_jsonb(hstore_array);
    
    drop function temp_hstore_array_to_jsonb(hstore[]);
    
    -- optionally rename column
    
  2. 创建另一列,复制转换后的数据并删除原始列

    alter table table_name
      add column jsonb_copy jsonb;
    
    update table_name
    set    jsonb_copy = (select json_agg(hstore_to_json(h))
                         from   unnest(hstore_array) h)::jsonb;
    
    alter table table_name drop column hstore_array;
    
    -- optionally rename column back like the dropped one
    

    但是后一个有一个弱点:旧列(要删除)可能有依赖对象,这会使实际删除变得更难(CASCADE 也会删除它们,但可能不会你想要什么)。