Xav
Xav

Reputation: 13

Postgresql: How to convert JSONb keys into an ENUM list?

I'm currently cleaning some tables in our application, and we have some JSONb defined in some tables, whose values are just true or false for a given key. Seeing that, i want to get rid of the jsonb, to have instead an enum array, in which i could get the former keys of my jsonb (whose value was true)

For instance, i want to transform this table

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

to

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

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

And i want the data to be migrated from (for this example)

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

to

['key1','key4']

I'm trying to alter my colum type by doing the data migration by a unique command, which i think could be something of:

ALTER TABLE
    my_table
    ALTER COLUMN
        my_field
    TYPE
        field_enum
    USING __XXXXXX___;

The using part is where i have difficulties, anybody has an idea of how i should alter my column without losing data?

I'm also open to create a new field and rename it after that, and use an UPDATE on the table.

I was thinking of using the jsonb_object_keys function but it first gives me all keys, and not just those whose values are true, and it also gives me an record[] which i don't manage to cast as a enum[].

Even more deeper, but it is not mandatory for me as i can do it as a post-treatment, it may happen that the json keys has to be linked to a enum key that is not the same, lets say that key1 should be converted as NEW_KEY(upper_case and name changing). Do you think it's possible to include in the same postgresql command?

If anybody of you has an idea of what i could do, i would appreciate any help.

Thanks !

X.

Upvotes: 1

Views: 1195

Answers (1)

klin
klin

Reputation: 121604

You need a function to convert a json object to your enum array:

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.

Upvotes: 1

Related Questions