PostgreSQL: Spalte aus der Ansicht löschen

10

Ich habe einen Ort, VIEWfür den ich versuche, ein Evolutionsskript zu erstellen, damit ich ihm eine Spalte hinzufügen kann. Dieser Teil funktioniert gut; Spalte gut hinzugefügt. Das Gegenteil funktioniert jedoch nicht. Das Entfernen der zuletzt hinzugefügten Spalte schlägt mit einer ERROR: cannot drop columns from viewNachricht fehl . Das Problem ist, dass diese spezielle Ansicht viele Referenzen hat, sowohl von als auch bis, daher kann ich nicht nur DROP CASCADEdas verdammte Ding!

Gibt es einen Grund, warum ich eine neu hinzugefügte Spalte nicht aus einer bestimmten entfernen kann VIEW? Was kann ich dann tun, um diese Aufgabe zu erfüllen?

(Hinweis: Die Umstände hier sind wie sie sind, aber ich kann in vielen anderen Fällen sehr gut eine ähnliche Situation sehen, auch bekannt als Löschen einer Spalte aus einer Ansicht.)

Yanick Rochon
quelle
Wie haben Sie die Spalte überhaupt hinzugefügt? Das kannst du nicht ALTER VIEW ... ADD COLUMN. Sind Sie mit CREATE OR REPLACE VIEW? Zeigen Sie bitte Ihren Code .
Craig Ringer
@CraigRinger, ja, CREATE OR REPLACE VIEWmit demselben Def, außer einer zusätzlichen Spalte (da in einer ref'ed-Tabelle eine neue Spalte hinzugefügt wurde, muss die Ansicht diese enthalten). Die "Devolution" entfernt die Spalte aus der ref'ed-Tabelle, so dass VIEWsie auch nicht mehr zurückgegeben werden muss.
Yanick Rochon

Antworten:

13

PostgreSQL (true bis mindestens 9.4) unterstützt derzeit das Entfernen einer Spalte mit nicht CREATE OR REPLACE VIEW.

Die neue Abfrage muss dieselben Spalten generieren, die von der vorhandenen Ansichtsabfrage generiert wurden (dh dieselben Spaltennamen in derselben Reihenfolge und mit denselben Datentypen), kann jedoch zusätzliche Spalten am Ende der Liste hinzufügen.

Es gibt keinen fundamentalen Grund, warum die Unterstützung für das Löschen von Spalten nicht hinzugefügt werden konnte, aber noch hat niemand die für die Implementierung erforderliche Arbeit geleistet.

CREATE OR REPLACE VIEWmüsste rekursiv alle Abhängigkeiten scannen und sicherstellen, dass keine von ihnen auf die zu löschende Spalte verweist. Wenn sie es verwenden würden SELECT *, müsste es die Spalte aus der Erweiterung von *in der Abhängigkeit entfernen und dann auch ihre Abhängigkeiten scannen . Damit ist einiges an Arbeit verbunden, und in einigen Bereichen ist nicht klar, wie genau sich das Löschen der Spalte verhalten soll, insbesondere bei Interaktionen mit Dump und Reload. Daher wollte noch niemand das Feature genug, um es zu implementieren. Patches und / oder Sponsoring der Entwicklung sind willkommen.

Sie müssen die Ansicht und alles, was davon abhängt, löschen und dann neu erstellen und ihre Abhängigkeiten neu erstellen. (Dasselbe galt früher für das Hinzufügen einer Spalte zu einer Ansicht; die Unterstützung für das Hinzufügen von Spalten wurde in 8.4 eingeführt.)

Beachten Sie, dass im Allgemeinen keine Erwartung besteht, dass DDL reversibel ist. Das Konzept der "Devolutions" ist wirklich fehlerhaft. Wenn Sie beispielsweise eine Spalte löschen und dann erneut hinzufügen, sind die Daten immer noch nicht mehr vorhanden.

Craig Ringer
quelle
1
Sie sagen also, dass immer dann, wenn eine große Anwendung mit komplexen Beziehungen eine Spalte ändern muss, die gesamte (oder zumindest ein Großteil der) DDL neu erstellt werden muss? Ich habe nicht viel Erfahrung mit Postgre, aber da ich von mySQL komme, hatte ich noch nie solche Probleme (mit Oracle, SQL Server oder MySQL), und es scheint mir seltsam, dass die Änderung nicht einfach durchgeführt werden kann und Fehler (wenn any) wird stattdessen zur Ausführungszeit geworfen. Diese Einschränkung ist sehr restriktiv.
Yanick Rochon
@YanickRochon Ja, es ist ein Schmerz, und ich würde gerne sehen, wie es verbessert wird. Wenn Sie dazu beitragen möchten, sollten Sie die Finanzierung in Betracht ziehen. Siehe postgresql.org/support/professional_support .
Craig Ringer
Wir sind zu klein, um ein solches Unternehmen zu finanzieren. Aber froh zu sehen, dass es kein festes Thema ist.
Yanick Rochon
1
@YanickRochon Fair genug. Es befindet sich im TODO - "Neukompilierung von Ansichten / Regeln zulassen, wenn sich die zugrunde liegende Tabelle ändert", wiki.postgresql.org/wiki/Todo#Views_and_Rules .
Craig Ringer