【问题标题】:Postgresql: How to convert JSONb keys into an ENUM list?Postgresql:如何将 JSONb 键转换为 ENUM 列表?
【发布时间】:2021-05-16 16:28:40
【问题描述】:

我目前正在清理我们应用程序中的一些表,我们在一些表中定义了一些 JSONb,它们的值只是给定键的 truefalse。看到这一点,我想摆脱 jsonb,取而代之的是一个 enum 数组,我可以在其中获取我的 jsonb 以前的键(其值为 true)

例如,我想改造这张桌子

CREATE TABLE my_table (
   ...
   my_field   JSONB
   ...
);

CREATE TYPE field_enum AS ENUM (
   'key1',
   'key2',
   'key3',
   'key4',
   'key5',
   'key6'
);

CREATE TABLE my_table (
   ...
   my_field   field_enum[] DEFAULT NULL,
   ...
);

我希望从中迁移数据(对于此示例)

{"key1": true, "key2": null, "key3": false, "key4": true}

['key1','key4']

我正在尝试通过一个独特的命令进行数据迁移来改变我的列类型,我认为这可能是:

ALTER TABLE
    my_table
    ALTER COLUMN
        my_field
    TYPE
        field_enum
    USING __XXXXXX___;

using 部分是我遇到困难的地方,有人知道我应该如何在不丢失数据的情况下更改我的列吗?

我也愿意创建一个新字段并在此之后重命名它,然后在表上使用 UPDATE。

我正在考虑使用jsonb_object_keys 函数,但它首先给了我所有的键,而不仅仅是那些值为真的键,它还给了我一个我无法将其转换为枚举的记录 [] []。

更深入,但这对我来说不是强制性的,因为我可以将其作为后处理,可能会发生 json 键必须链接到一个不相同的枚举键,假设 @ 987654330@ 应转换为 NEW_KEY(大写和名称更改)。你认为可以包含在同一个 postgresql 命令中吗?

如果你们中的任何人知道我能做什么,我将不胜感激。

谢谢!

X.

【问题讨论】:

  • 你为什么不完全展开它并只拥有 6 个布尔列?查询此类标志会更容易。
  • 我想过这个想法,但考虑到我的桌子上有 6 个 JSONB,JSONB 有大约 10 个键,假设我们有一个反应下拉组件,可以轻松地将 ENUM 列表作为输入,它是在我的表上有 6 个 ENUM[] 字段而不是 60 个字段,非常方便且易读。

标签: database postgresql enums jsonb


【解决方案1】:

您需要一个函数将 json 对象转换为您的枚举数组:

create or replace function jsonb_to_field_enums(jsonb)
returns field_enum[] language sql immutable
as $$
    select array_agg(key)::field_enum[]
    from jsonb_each_text($1)
    where value::bool
$$;

Db<>fidlle.

【讨论】:

  • 哦,太好了,效果很好!使用这种方法,我可以轻松地定义一个新字段并在我的表上使用 UPDATE 来获取我的新字段中的值,然后删除我以前的 JSONB 字段并用以前的字段名称重命名新字段。那行得通。无论如何,您知道我是否可以直接在USING 中使用此方法,这样我就可以避免添加新字段的部分?
  • 当然可以在alter table中使用。您似乎没有注意到答案底部的Db<>fidlle 链接。单击它以查看完整示例。
  • 啊,是的,你是对的,我没有看到链接!效果很好!谢谢您的帮助 !欣赏它!
猜你喜欢
  • 2018-03-07
  • 2011-07-18
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
  • 1970-01-01
相关资源
最近更新 更多