Я работаю над кодом для раскрутки данных, упакованных в JSONB с обычным форматом для передачи в другую систему.
- Postgres 11.4.
- Формат JSON известен заранее, он указан в записи.
- У меня есть определенный тип для формата JSON.
Вот урезанная промежуточная таблица:
CREATE TABLE IF NOT EXISTS data.domo_passthrough (
id uuid NOT NULL DEFAULT extensions.gen_random_uuid (),
type_name text NOT NULL DEFAULT NULL,
report_data jsonb NOT NULL DEFAULT '{}',
CONSTRAINT domo_passthrough_id_pkey
PRIMARY KEY (id)
);
Поле report_data
содержит упакованные данные, поле type_name
включает название формата, например, это:
create type data.table_stats_type as (
table_name text,
record_count integer,
table_number integer)
Этот код работает правильно, чтобы распаковать данные в три столбца, определенных в типе:
select expanded_data.*
from domo_passthrough,
jsonb_populate_recordset(null::table_stats_type, report_data) as expanded_data;
Что я хотел бы сделать, если это возможно, это передать имя-типав качестве аргумента jsonb_populate_recordset
:
select expanded_data.*
from domo_passthrough,
jsonb_populate_recordset(null::type_name, report_data) as expanded_data;
Это не работает, а null::type_name
возвращает ошибку:
ERROR: type "type_name" does not exist
LINE 3: jsonb_populate_recordset(null::type_name, report_data..
Справедливо. Тип_имя - это текст, а не литерал. Я надеюсь, что есть хороший способ сделать то, что я после. (Я понимаю, что в данный момент мне нужно не испортить присвоения имен типов в данных.) Возможности:
- какая-то операция ::casting
, но я не могу понять, какой типЯ бы использовал от null::
до type_name
. Я нашел функцию pg_typeof
, но не вижу способа применить ее для построения кода.
- Динамический SQL в функции. Кажется, это возможно, но я надеюсь на что-то более простое.
- Некоторые другие функции или опции, о которых я не знаю.
ВОЗВРАТ НАСТРОЙКИ Функция?
Спасибо за комментарий, я подумал, что попробую написать функцию ... и я был озадачен. Всегда сложно получить динамические результаты из SQL. Я не жалуюсь на это ... но это один раз, когда я хотел бы иметь обобщенный инструмент. Это звучит так, как будто RETURN SETOF RECORD
должно работать, но у меня ничего не получилось. Я просмотрел несколько тем и документов, но я все еще в тупике. Вот функция PG / pgSQL, так как я не смог заставить работать версию на чистом SQL:
DROP FUNCTION IF EXISTS api.domo_passthrough_expand (text, jsonb);
CREATE FUNCTION api.domo_passthrough_expand(type_name text, packed_data jsonb)
RETURNS SETOF record AS
$BODY$
BEGIN
RETURN QUERY EXECUTE FORMAT
'select *
from jsonb_populate_recordset(null::%1$I, %2$I) as expanded_data;',
type_name,
packed_data;
END;
$BODY$
LANGUAGE plpgsql;
ALTER FUNCTION api.domo_passthrough_expand(text, jsonb) OWNER TO user_bender;
select expanded.*
from domo_passthrough,
domo_passthrough_expand(domo_passthrough.type_name,domo_passthrough.report_data)
ERROR: a column definition list is required for functions returning "record"
LINE 4: domo_passthrough_expand(domo_passthrough.type_name,domo...
Есть ли способ сделать мое расширение в общем случае с помощью функции? Если нет, я могу подходить к чему-то другому, но я бы предпочел, чтобы все было на стороне Postgres.