У меня есть таблица, включающая поле JSONB с массивом JSON в простом формате, который я хотел бы расширить. Вот уменьшенная версия определения таблицы:
CREATE TABLE IF NOT EXISTS data.data_file_info (
id uuid NOT NULL,
server_name_ citext NOT NULL,
table_stats jsonb DEFAULT '{}'::jsonb NOT NULL,
PRIMARY KEY(id)
);
Вот несколько примеров данных из поля JSONB table_stats:
[
{"table_name":"AutoReportOrg","record_count":48,"table_number":167},
{"table_name":"AutoReportOrgAudit","record_count":0,"table_number":170},
{"table_name":"AutoReportOrgRecipient","record_count":126,"table_number":168},
{"table_name":"AutoReportRecipient","record_count":28,"table_number":169}
]
json_populate_recordset и / или json_to_recordset функции кажутся такими, какими я должен быть, но я не смог заставить их работать. Я посмотрел на многие прошлые вопросы и попробовал различные синтаксические элементы. Вот то, что я получаю впечатление должно работать ... но это не так:
-- Define a custom type to act as a template for the JSON parser.
DROP TYPE IF EXISTS dfits;
CREATE TYPE api.dfits AS (
table_name citext,
record_count int8,
table_number int4);
-- And now we parse!
SELECT server_name_, (json_populate_recordset(null::dfits, table_stats)).* FROM data_file_info;
Но я получаю это обратно:
ERROR: function json_populate_recordset(dfits, jsonb) does not exist
LINE 4: SELECT server_name_, (json_populate_recordset(null::dfits, t...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts. (Line 9)
Может кто-нибудь заметить ошибку в моей настройке? Кажется, у меня есть нужные части, но я не могу их правильно собрать.
Postgres 11.4, развернутый на RDS.
Follow Up
GMB ответил на мой вопрос, но я хочу добавить сюда немного больше для архивов. В прошлом, когда я печатал ошибку (JSON вместо JSONB), суть всего этого заключается в том, что Postgres нужен шаблон / карта, которая определяет структуру элементов в массиве JSON / JSONB. Я думаю, что в этом случае есть четыре (?) Места, откуда могут поступать данные для набора:
- Существующее определение таблицы, поскольку каждая таблица является типом.
- Существующее представлениеопределение, так как каждое представление является типом. (Вы можете найти их в pg_class вместе с базовыми производными от таблицы типами.
- Пользовательский тип, созданный с помощью
CREATE TYPE
, как я использовал выше. - In-Объявление строки.
Для сравнения, вот обновленный запрос, который использует пользовательский тип dfits
, показанный выше:
SELECT server_name_, expanded_json.*
FROM
data_file_info,
jsonb_populate_recordset(null::dfits, table_stats) as expanded_json
А теперь вот еще одна версия, которая использует in-lineобъявление:
SELECT server_name_, expanded_json.*
FROM
data_file_info,
jsonb_to_recordset(table_stats) as expanded_json
(table_name text, record_count int, table_number int)
Я вижу варианты использования любого из этих подходов, но, с учетом сказанного, CREATE TYPE
довольно хорошо. И вы можете комбинировать его с CREATE CAST
, чтобы сделать его очень компактным и простым в использовании-используйте код.