Запросите определение материализованного представления в Postgres

21

Мне интересно, как запросить определение материализованного представления в Postgres. Для справки, то, что я надеялся сделать, очень похоже на то, что вы можете сделать для обычного просмотра:

SELECT * FROM information_schema.views WHERE table_name = 'some_view';

который дает вам следующие столбцы:

table_catalog
table_schema
table_name
view_definition
check_option
is_updatable
is_insertable_into
is_trigger_updatable
is_trigger_deletable
is_trigger_insertable_into

Возможно ли это для материализованных представлений?

Из моих исследований покажется, что материализованные взгляды преднамеренно исключены из information_schema, потому что

Информационная_схема может показывать только те объекты, которые существуют в стандарте SQL.

( http://www.postgresql.org/message-id/3794.1412980686@sss.pgh.pa.us )

Поскольку они, похоже, полностью исключены из information_schema, я не уверен, как это сделать, но я хотел бы сделать что-то двойное:

  1. Запросить, существует ли конкретный материализованный вид. (Пока что единственный способ сделать это - попытаться создать вид с тем же именем и посмотреть, не взорвется ли он.)
  2. А затем запросите определение материализованного представления (аналогично view_definitionстолбцу на information_schema.views).
Шон Боб
источник
Несколько связанный с этим вопрос о запросе уникальных ограничений для материализованных представлений: dba.stackexchange.com/questions/101899
Шон Бин
Вас заинтересует быстрый способ проверки существования: SELECT to_regclass('some_schema.some_mat_view')- если он найден, он не обязательно должен быть MV. Подробности: stackoverflow.com/questions/20582500/…
Эрвин Брандштеттер
Также: stackoverflow.com/questions/23092983/…
Эрвин Брандстеттер

Ответы:

13

Оказывается, это было не так сложно, как я думал! (С небольшим знанием pg_catalog ...)

Часть 1. Запрос, существует ли материализованное представление:

SELECT count(*) > 0
FROM pg_catalog.pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'm'
AND n.nspname = 'some_schema'
AND c.relname = 'some_mat_view';

Легко и приятно.

Часть 2: запрос определения материализованного представления:

Для того, чтобы получить запрос, чтобы получить определение представления mat, мне сначала нужно было найти определение information_schema.viewsпредставления, выполнив:

SELECT view_definition
FROM information_schema.views
WHERE table_schema = 'information_schema'
AND table_name = 'views';

Затем я скопировал запрос и изменил c.relkind = 'v'::"char"на c.relkind = 'm'::"char", чтобы получить матовые представления (вместо обычных представлений). Смотрите полный запрос здесь: http://pastebin.com/p60xwfes

На данный момент вы можете довольно легко добавить AND c.relname = 'some_mat_view'и запустить его, чтобы получить определение some_mat_view.

Но вам все равно придется делать это снова и снова, когда вы захотите посмотреть определение вида коврика ...

Бонус: создайте вид, чтобы сделать это проще

Я решил создать новое представление, чтобы упростить поиск определений в будущем. Я просто добавил CREATE VIEW materialized_views ASк началу запроса, связанного выше, чтобы создать новое представление, и теперь я могу сделать запрос следующим образом:

SELECT *
FROM materialized_views
WHERE table_schema = 'some_schema'
AND table_name = 'some_mat_view';

Намного лучше!

Я также могу использовать это представление, чтобы легко запросить, существует ли материализованное представление, изменив *на count(*) > 0.

Отказ от ответственности : я не знаю, что остальные столбцы в результатах запроса полностью верны, поскольку материализованные представления принципиально отличаются от стандартных представлений (я думаю, что они правы). Но это по крайней мере запросить table_schema, table_nameи view_definitionправильно.

Шон Боб
источник
0

Недостаток других ответов здесь заключается в том, что вы просто получаете определение SQL, в то время как в большинстве случаев вам интересны фактические столбцы и возможность манипулировать ими как текстом. Ниже приведен мой ответ на аналогичный вопрос , который включает имена столбцов и типы данных:

Я не могу сказать, что полностью понимаю базовую модель данных, поэтому используйте мое решение ниже с небольшим количеством соли:

select 
    ns.nspname as schema_name, 
    cls.relname as table_name, 
    attr.attname as column_name,
    trim(leading '_' from tp.typname) as datatype
from pg_catalog.pg_attribute as attr
join pg_catalog.pg_class as cls on cls.oid = attr.attrelid
join pg_catalog.pg_namespace as ns on ns.oid = cls.relnamespace
join pg_catalog.pg_type as tp on tp.typelem = attr.atttypid
where 
    ns.nspname = 'your_schema' and
    cls.relname = 'your_materialized_view' and 
    not attr.attisdropped and 
    cast(tp.typanalyze as text) = 'array_typanalyze' and 
    attr.attnum > 0
order by 
    attr.attnum

Вы должны изменить 'your_schema'и 'your_materialized_view'.

Андре Кристоффер Андерсен
источник