Consultar a definição de uma visão materializada no Postgres


21

Eu estou querendo saber como consultar a definição de uma visão materializada no Postgres. Para referência, o que eu esperava fazer é muito semelhante ao que você pode fazer para uma exibição regular:

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

que fornece as seguintes colunas:

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

Isso é possível para visualizações materializadas?

De minhas pesquisas até agora, parece que as visualizações materializadas são deliberadamente excluídas do information_schema, porque

O information_schema pode mostrar apenas objetos que existem no padrão SQL.

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

Como eles parecem ser totalmente excluídos do information_schema, não sei como fazer isso, mas o que eu gostaria de fazer é duplo:

  1. Pergunte se existe uma exibição materializada específica. (Até agora, a única maneira que encontrei para fazer isso é tentar criar uma exibição de tapete com o mesmo nome e ver se ela explode.)
  2. E, em seguida, consulte a definição da visualização materializada (semelhante à view_definitioncoluna information_schema.views).

Pergunta algo relacionado-sobre como consultar para limitações exclusivas em visões materializadas: dba.stackexchange.com/questions/101899
Sean Bean

Você estará interessado na maneira rápida de testar a existência: SELECT to_regclass('some_schema.some_mat_view')- se encontrado, não precisa ser um MV. Detalhes: stackoverflow.com/questions/20582500/…
Erwin Brandstetter

Respostas:



13

Acontece que isso não foi tão complicado quanto eu pensava! (Com apenas um pouco de conhecimento de pg_catalog ...)

Parte 1: consulte se existe uma exibição materializada:

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';

Legal e fácil.

Parte 2: consulte a definição de uma visão materializada:

Para criar uma consulta para obter a definição da exibição de tapete, primeiro tive que procurar a definição da information_schema.viewsexibição executando:

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

Em seguida, copiei a consulta e mudei c.relkind = 'v'::"char"para c.relkind = 'm'::"char"para obter visualizações de esteira (em vez de visualizações regulares). Veja a consulta completa aqui: http://pastebin.com/p60xwfes

Neste ponto, você pode facilmente adicioná AND c.relname = 'some_mat_view'-lo e executá-lo para obter a definição de some_mat_view.

Mas você ainda precisará fazer isso novamente da próxima vez que desejar pesquisar a definição de uma exibição de tapete ...

Bônus: crie uma visualização para facilitar isso

Optei por criar uma nova visualização para facilitar a pesquisa de definições de visualização de esteira no futuro. Basicamente, acabei de adicionar CREATE VIEW materialized_views ASo início da consulta vinculada acima para criar a nova visualização e agora posso consultá-la da seguinte forma:

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

Muito melhor!

Também posso usar essa visualização para consultar facilmente se existe uma visualização materializada, alterando *para count(*) > 0.

Isenção de responsabilidade : não sei, as outras colunas nos resultados da consulta estão totalmente corretas, pois as visualizações materializadas são fundamentalmente diferentes das visualizações padrão ( acho que estão corretas). Mas isso faz pelo menos a consulta table_schema, table_namee view_definitioncorretamente.


0

A desvantagem das outras respostas aqui é que você apenas obtém a definição SQL, enquanto na maioria dos casos você está interessado nas colunas reais e pode manipulá-las como texto. A seguir, é minha resposta de uma pergunta semelhante , que inclui nomes de colunas e tipos de dados:

Não posso dizer que entendi completamente o modelo de dados subjacente; portanto, use minha solução abaixo com um pouco de sal:

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

Você tem que mudar 'your_schema'e 'your_materialized_view'.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.