Consultar la definición de una vista materializada en Postgres


21

Me pregunto cómo consultar la definición de una vista materializada en Postgres. Como referencia, lo que esperaba hacer es muy similar a lo que puede hacer para una vista normal:

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

que te da las siguientes columnas:

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

¿Es esto posible para vistas materializadas?

Según mi investigación hasta el momento, parece que las vistas materializadas se excluyen deliberadamente del esquema de información, porque

Information_schema solo puede mostrar objetos que existen en el estándar SQL.

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

Como parecen estar completamente excluidos del esquema de información, no estoy seguro de cómo hacerlo, pero lo que me gustaría hacer es doble:

  1. Pregunte si existe una vista materializada particular. (Hasta ahora, la única forma en que he encontrado para hacer esto es intentar crear una vista mate con el mismo nombre y ver si explota).
  2. Y luego consulte la definición de la vista materializada (similar a la view_definitioncolumna en information_schema.views).

Pregunta algo relacionada con la consulta de restricciones únicas en vistas materializadas: dba.stackexchange.com/questions/101899
Sean the Bean

Te interesará la forma rápida de probar la existencia: SELECT to_regclass('some_schema.some_mat_view')si se encuentra, no tiene que ser un MV. Detalles: stackoverflow.com/questions/20582500/…
Erwin Brandstetter

Respuestas:



13

¡Resulta que esto no fue tan complicado como pensaba! (Con un poco de conocimiento de pg_catalog ...)

Parte 1: consulta si existe una vista 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';

Bonito y fácil.

Parte 2: Consulta la definición de una vista materializada:

Para llegar a una consulta para obtener la definición de la vista mat, primero tuve que buscar la definición de la information_schema.viewsvista ejecutando:

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

Luego copié la consulta y cambié c.relkind = 'v'::"char"a c.relkind = 'm'::"char"para obtener vistas matizadas (en lugar de vistas normales). Vea la consulta completa aquí: http://pastebin.com/p60xwfes

En este punto, podría agregarlo AND c.relname = 'some_mat_view'y ejecutarlo con bastante facilidad para obtener la definición de some_mat_view.

Pero aún tendrá que volver a hacer esto la próxima vez que desee buscar la definición de una vista de mat ...

Bonificación: cree una vista para facilitar esto

Opté por crear una nueva vista para que sea más fácil buscar definiciones de vista mat en el futuro. Básicamente, acabo de agregar CREATE VIEW materialized_views ASal comienzo de la consulta vinculada anteriormente para crear la nueva vista, y ahora puedo consultarla así:

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

¡Mucho mejor!

También puedo usar esta vista para consultar fácilmente si existe una vista materializada al cambiar *a count(*) > 0.

Descargo de responsabilidad : no lo sé, las otras columnas en los resultados de la consulta son completamente correctas, ya que las vistas materializadas son fundamentalmente diferentes de las vistas estándar ( creo que son correctas). Pero esto al menos consulta el table_schema, table_namey view_definitioncorrectamente.


0

El inconveniente con las otras respuestas aquí es que solo obtienes la definición de SQL, mientras que en la mayoría de los casos estás interesado en las columnas reales y puedes manipularlas como texto. La siguiente es mi respuesta de una pregunta similar , que incluye nombres de columna y tipos de datos:

No puedo decir que entiendo completamente el modelo de datos subyacente, así que use mi solución a continuación con un grano 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

Tienes que cambiar 'your_schema'y 'your_materialized_view'.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.