Interroga la definizione di una vista materializzata in Postgres


21

Mi chiedo come interrogare la definizione di una vista materializzata in Postgres. Per riferimento, quello che speravo di fare è molto simile a quello che puoi fare per una visione normale:

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

che ti dà le seguenti colonne:

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

È possibile per viste materializzate?

Dalla mia ricerca finora, sembra che le opinioni materializzate siano deliberatamente escluse da information_schema, perché

Information_schema può mostrare solo oggetti esistenti nello standard SQL.

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

Dal momento che sembrano essere completamente esclusi da information_schema, non sono sicuro di come procedere, ma quello che mi piacerebbe fare è duplice:

  1. Chiedere se esiste una particolare vista materializzata. (Finora l'unico modo che ho trovato per farlo è provare a creare una vista mat con lo stesso nome e vedere se esplode.)
  2. Quindi interroga la definizione della vista materializzata (simile alla view_definitioncolonna attivata information_schema.views).

Domanda in qualche modo correlata alla ricerca di vincoli univoci per le viste materializzate: dba.stackexchange.com/questions/101899
Sean the Bean

Sarai interessato al modo rapido per testare l'esistenza: SELECT to_regclass('some_schema.some_mat_view')- se trovato, non deve essere un MV, però. Dettagli: stackoverflow.com/questions/20582500/…
Erwin Brandstetter,

Risposte:



13

Si scopre che non è stato così complicato come pensavo! (Con solo una piccola conoscenza di pg_catalog ...)

Parte 1: query sull'esistenza di una vista materializzata:

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

Bello e facile.

Parte 2: eseguire una query sulla definizione di una vista materializzata:

Per trovare una query per ottenere la definizione della vista mat, per prima cosa ho dovuto cercare la definizione della information_schema.viewsvista eseguendo:

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

Quindi ho copiato la query e modificato in c.relkind = 'v'::"char"al c.relkind = 'm'::"char"fine di ottenere visualizzazioni mat (invece di visualizzazioni normali). Vedi la query completa qui: http://pastebin.com/p60xwfes

A questo punto potresti facilmente aggiungerlo AND c.relname = 'some_mat_view'ed eseguirlo per ottenere la definizione di some_mat_view.

Ma dovresti ancora ripetere tutto la prossima volta che vuoi cercare la definizione di una vista mat ...

Bonus: crea una vista per renderlo più semplice

Ho scelto di creare una nuova vista per rendere più semplice la ricerca delle definizioni delle viste mat in futuro. Fondamentalmente ho appena aggiunto CREATE VIEW materialized_views ASall'inizio della query collegata sopra per creare la nuova vista e ora posso interrogarla in questo modo:

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

Molto meglio!

Posso anche usare questa vista per interrogare facilmente se esiste una vista materializzata cambiando *in count(*) > 0.

Dichiarazione di non responsabilità : non lo so, le altre colonne nei risultati della query sono del tutto corrette, poiché le viste materializzate sono fondamentalmente diverse dalle viste standard (penso che abbiano ragione). Ma questo almeno interroga table_schema, table_namee view_definitioncorrettamente.


0

Lo svantaggio con le altre risposte qui è che ottieni solo la definizione SQL, mentre nella maggior parte dei casi sei interessato alle colonne effettive e puoi manipolarle come testo. Di seguito è la mia risposta da una domanda simile , che include nomi di colonna e tipi di dati:

Non posso dire di aver compreso appieno il modello di dati sottostante, quindi usa la mia soluzione di seguito con un pizzico di sale:

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

Devi cambiare 'your_schema'e 'your_materialized_view'.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.