将 jsonb 列转换为用户定义的类型
Convert jsonb column to a user-defined type
我正在尝试将 jsonb 列中的每一行转换为我定义的类型,但我似乎做不到。
我有一个应用程序可以从 The Guardian Open Platform 抓取文章并将响应(作为 jsonb)转储到一个名为 'body' 的列中 table。其他列是顺序 ID 和从响应负载中提取的时间戳,可帮助我的应用仅抓取新数据。
我想将响应转储数据移动到正确定义的 table 中,据我所知,我已经定义了一个类型 (my_type
)。
我一直在参考 Postgres 文档中的 9.16. JSON Functions and Operators。我可以得到一条记录作为我的类型:
select * from jsonb_populate_record(null::my_type, (select body from data_ingestion limit 1));
产生
id
type
sectionId
...
example_id
example_type
example_section_id
...
(简写)
如果我删除限制,我会收到一个错误,这是有道理的:子查询将向 jsonb_populate_record
提供多行,但只需要一个。
我可以让它做多行,但结果没有分成几列:
select jsonb_populate_record(null::my_type, body) from reviews_ingestion limit 3;
产生:
jsonb_populate_record
(example_id_1,example_type_1,example_section_id_1,...)
(example_id_2,example_type_2,example_section_id_2,...)
(example_id_3,example_type_3,example_section_id_3,...)
这有点奇怪,我本以为会看到列名;这毕竟是提供类型的重点。
我知道我可以通过使用 Postgres JSON 查询功能来做到这一点,例如
select
body -> 'id' as id,
body -> 'type' as type,
body -> 'sectionId' as section_id,
...
from reviews_ingestion;
这行得通,但看起来很不雅观。另外我丢失了数据类型。
我还考虑过将 body
列中的所有行聚合到一个 JSON 数组中,以便能够将其提供给 jsonb_populate_recordset
但这似乎有点一种愚蠢的方法,而且不太可能高效。
有没有办法使用 Postgres 函数实现我想要的?
也许您需要这个 - 将 my_type
记录分成几列:
select (jsonb_populate_record(null::my_type, body)).*
from reviews_ingestion
limit 3;
-- or whatever other query clauses here
即select 全部来自这些 my_type
记录。所有列名和类型都已到位。
这是一个例子。我的自定义类型是 delmet
,CTO t
远程模仿 data_ingestion
。
create type delmet as (x integer, y text, z boolean);
with t(i, j, k) as
(
values
(1, '{"x":10, "y":"Nope", "z":true}'::jsonb, 'cats'),
(2, '{"x":11, "y":"Yep", "z":false}', 'dogs'),
(3, '{"x":12, "y":null, "z":true}', 'parrots')
)
select i, (jsonb_populate_record(null::delmet, j)).*, k
from t;
结果:
i
x
y
z
k
1
10
Nope
true
cats
2
11
Yep
false
dogs
3
12
true
parrots
我正在尝试将 jsonb 列中的每一行转换为我定义的类型,但我似乎做不到。
我有一个应用程序可以从 The Guardian Open Platform 抓取文章并将响应(作为 jsonb)转储到一个名为 'body' 的列中 table。其他列是顺序 ID 和从响应负载中提取的时间戳,可帮助我的应用仅抓取新数据。
我想将响应转储数据移动到正确定义的 table 中,据我所知,我已经定义了一个类型 (my_type
)。
我一直在参考 Postgres 文档中的 9.16. JSON Functions and Operators。我可以得到一条记录作为我的类型:
select * from jsonb_populate_record(null::my_type, (select body from data_ingestion limit 1));
产生
id | type | sectionId | ... |
---|---|---|---|
example_id | example_type | example_section_id | ... |
(简写)
如果我删除限制,我会收到一个错误,这是有道理的:子查询将向 jsonb_populate_record
提供多行,但只需要一个。
我可以让它做多行,但结果没有分成几列:
select jsonb_populate_record(null::my_type, body) from reviews_ingestion limit 3;
产生:
jsonb_populate_record |
---|
(example_id_1,example_type_1,example_section_id_1,...) |
(example_id_2,example_type_2,example_section_id_2,...) |
(example_id_3,example_type_3,example_section_id_3,...) |
这有点奇怪,我本以为会看到列名;这毕竟是提供类型的重点。
我知道我可以通过使用 Postgres JSON 查询功能来做到这一点,例如
select
body -> 'id' as id,
body -> 'type' as type,
body -> 'sectionId' as section_id,
...
from reviews_ingestion;
这行得通,但看起来很不雅观。另外我丢失了数据类型。
我还考虑过将 body
列中的所有行聚合到一个 JSON 数组中,以便能够将其提供给 jsonb_populate_recordset
但这似乎有点一种愚蠢的方法,而且不太可能高效。
有没有办法使用 Postgres 函数实现我想要的?
也许您需要这个 - 将 my_type
记录分成几列:
select (jsonb_populate_record(null::my_type, body)).*
from reviews_ingestion
limit 3;
-- or whatever other query clauses here
即select 全部来自这些 my_type
记录。所有列名和类型都已到位。
这是一个例子。我的自定义类型是 delmet
,CTO t
远程模仿 data_ingestion
。
create type delmet as (x integer, y text, z boolean);
with t(i, j, k) as
(
values
(1, '{"x":10, "y":"Nope", "z":true}'::jsonb, 'cats'),
(2, '{"x":11, "y":"Yep", "z":false}', 'dogs'),
(3, '{"x":12, "y":null, "z":true}', 'parrots')
)
select i, (jsonb_populate_record(null::delmet, j)).*, k
from t;
结果:
i | x | y | z | k |
---|---|---|---|---|
1 | 10 | Nope | true | cats |
2 | 11 | Yep | false | dogs |
3 | 12 | true | parrots |