-1

We are trying to migrate data from an array column containing JSONB to a proper Postgres table.

{{"a":1,"b": 2, "c":"bar"},{"a": 2, "b": 3, "c":"baz"}}
 a |    b    | c
---+---------+---
 1 | 2        | "bar"
 2 | 3        | "baz"

As part of the process, we have made several attempts using functions like unnest and array_to_json. In the unnest case, we get several JSONB rows, but cannot figure out how to insert them into the second table. In the array_to_json case, we are able to cast the array to a JSON string, but the json_to_recordset does not seem to accept the JSON string from a common table expression.

What would be a good strategy to 'mirror' the array of JSONB items as a proper table, so that we can run the query inside of a stored procedure, triggered on insert?

3
  • 1
    Is the structure of the table (number, names and types of columns) known? Commented Jan 18, 2019 at 15:09
  • Yes, we have defined a second table with proper data types, and provided a schema mapping to the json_to_recordset call, as per the documentation. Commented Jan 18, 2019 at 15:26
  • After a bit more searching, the following looks relevant, although I don't fully understand why to use "cross join lateral" reddit.com/r/PostgreSQL/comments/2u6ah3/… Commented Jan 18, 2019 at 15:29

1 Answer 1

1

Use unnest() in a lateral join:

with my_data(json_column) as (
values (
    array['{"a":1,"b":2,"c":"bar"}','{"a":2,"b":3,"c":"baz"}']::jsonb[])
)
select 
    value->>'a' as a, 
    value->>'b' as b, 
    value->>'c' as c
from my_data
cross join unnest(json_column) as value

 a | b |  c  
---+---+-----
 1 | 2 | bar
 2 | 3 | baz
(2 rows)

You may need some casts or converts, e.g.:

select 
    (value->>'a')::int as a, 
    (value->>'b')::int as b, 
    (value->>'c')::text as c
from my_data
cross join unnest(json_column) as value

Lateral joining means that the function unnest() will be executed for each row from the main table. The function returns elements of the array as value.

Sign up to request clarification or add additional context in comments.

2 Comments

Ok, I did not think anyone could use such a strange construction as jsonb[]. It's definitely a kind of anti-pattern. See also: stackoverflow.com/a/46015221/1995738 and stackoverflow.com/a/37209754/1995738
Thanks for your feedback. I will try your suggestions ASAP.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.