Fragen Sie die Definition einer materialisierten Ansicht in Postgres ab

21

Ich frage mich, wie man die Definition einer materialisierten Ansicht in Postgres abfragt. Was ich als Referenz erhofft habe, ist sehr ähnlich dem, was Sie für eine reguläre Ansicht tun können:

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

Das gibt Ihnen die folgenden Spalten:

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

Ist dies für materialisierte Ansichten möglich?

Aus meiner bisherigen Forschung geht hervor, dass materialisierte Ansichten bewusst vom information_schema ausgeschlossen sind, weil

Das Informationsschema kann nur Objekte anzeigen, die im SQL-Standard vorhanden sind.

( http://www.postgresql.org/message-id/[email protected] )

Da sie von information_schema völlig ausgeschlossen zu sein scheinen, bin ich mir nicht sicher, wie ich vorgehen soll, aber ich möchte zwei Dinge tun:

  1. Abfrage, ob eine bestimmte materialisierte Ansicht vorhanden ist. (Bisher habe ich nur versucht, eine Mattenansicht mit demselben Namen zu erstellen und zu prüfen, ob sie in die Luft geht.)
  2. Fragen Sie anschließend die Definition der materialisierten Ansicht ab (ähnlich wie in der view_definitionSpalte "Ein" information_schema.views).
Sean the Bean
quelle
Etwas verwandte Frage zur Abfrage nach eindeutigen Einschränkungen für materialisierte Ansichten: dba.stackexchange.com/questions/101899
Sean the Bean
Sie werden an der schnellen Möglichkeit interessiert sein, das Vorhandensein zu testen: SELECT to_regclass('some_schema.some_mat_view')- Wenn es gefunden wird, muss es sich jedoch nicht um ein MV handeln. Details: stackoverflow.com/questions/20582500/…
Erwin Brandstetter
Also: stackoverflow.com/questions/23092983/…
Erwin Brandstetter

Antworten:

13

Es stellte sich heraus, dass dies nicht so kompliziert war, wie ich dachte! (Mit nur wenig Wissen über pg_catalog ...)

Teil 1: Abfrage, ob eine materialisierte Ansicht vorhanden ist:

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

Schön und leicht.

Teil 2: Abfragen der Definition einer materialisierten Ansicht:

Um eine Abfrage für die Definition der Mat-Ansicht zu erstellen, musste ich zuerst die Definition der information_schema.viewsAnsicht nachschlagen, indem ich Folgendes ausführte:

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

Dann habe ich die Abfrage kopiert und in geändert c.relkind = 'v'::"char", c.relkind = 'm'::"char"um Matte-Ansichten (anstelle von regulären Ansichten) zu erhalten. Die vollständige Abfrage finden Sie hier: http://pastebin.com/p60xwfes

Zu diesem Zeitpunkt können Sie es ziemlich einfach hinzufügen AND c.relname = 'some_mat_view'und ausführen, um die Definition von zu erhalten some_mat_view.

Sie müssen dies jedoch das nächste Mal erneut tun, wenn Sie die Definition einer Mattenansicht nachschlagen möchten ...

Bonus: Erstellen Sie eine Ansicht, um dies zu vereinfachen

Ich habe mich dafür entschieden, eine neue Ansicht zu erstellen, um das Nachschlagen von Mattenansichtsdefinitionen in Zukunft zu vereinfachen. Ich habe im Grunde nur CREATE VIEW materialized_views ASden Anfang der oben verlinkten Abfrage hinzugefügt , um die neue Ansicht zu erstellen, und jetzt kann ich sie wie folgt abfragen:

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

Viel besser!

Ich kann auch diese Ansicht leicht Abfrage , ob eine Ansicht durch eine Änderung materialisiert besteht *zu count(*) > 0.

Haftungsausschluss : Ich weiß nicht, dass die anderen Spalten in den Abfrageergebnissen völlig korrekt sind, da materialisierte Ansichten sich grundlegend von Standardansichten unterscheiden (ich denke, sie haben Recht). Aber das tut zumindest Abfrage der table_schema, table_nameund view_definitionrichtig.

Sean the Bean
quelle
0

Der Nachteil bei den anderen Antworten ist, dass Sie nur die SQL-Definition erhalten, während Sie in den meisten Fällen an den tatsächlichen Spalten interessiert sind und diese als Text bearbeiten können. Das Folgende ist meine Antwort von einer ähnlichen Frage , die Spaltennamen und Datentypen enthält:

Ich kann nicht sagen, dass ich das zugrunde liegende Datenmodell vollständig verstehe. Verwenden Sie daher die folgende Lösung mit einem Körnchen Salz:

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

Sie müssen sich ändern 'your_schema'und 'your_materialized_view'.

André Christoffer Andersen
quelle