PostgreSQL: supprimer la colonne de la vue

10

J'ai un VIEWoù j'essaye de créer un script d'évolution pour, donc je peux y ajouter une colonne. Cette partie fonctionne bien; colonne ajoutée très bien. Cependant, l'inverse ne fonctionne pas; supprimer cette dernière colonne ajoutée échoue avec un ERROR: cannot drop columns from viewmessage. Le problème est que cette vue particulière a de nombreuses références, à la fois de et vers, donc je ne peux pas juste DROP CASCADEla sacrée chose!

Y a-t-il une raison pour laquelle je ne peux pas supprimer une colonne nouvellement ajoutée d'une donnée VIEW? Alors, que puis-je faire pour accomplir cette tâche?

(Remarque: les circonstances, ici, sont ce qu'elles sont, mais je peux très bien voir une situation similaire, alias supprimer une colonne d'une vue, dans de nombreux autres cas.)

Yanick Rochon
la source
Comment avez-vous ajouté la colonne en premier lieu? Tu ne peux pas ALTER VIEW ... ADD COLUMN. Utilisez-vous CREATE OR REPLACE VIEW? Montrez votre code s'il vous plaît.
Craig Ringer
@CraigRinger, oui, CREATE OR REPLACE VIEWavec le même def, sauf une colonne supplémentaire (car une table ref'ed a une nouvelle colonne ajoutée, donc la vue doit l'inclure). La "dévolution" supprime la colonne de la table ref'ed, donc le VIEWdoit également ne plus la renvoyer.
Yanick Rochon

Réponses:

13

PostgreSQL (vrai jusqu'à au moins 9.4) ne prend actuellement pas en charge la suppression d'une colonne avec CREATE OR REPLACE VIEW.

La nouvelle requête doit générer les mêmes colonnes que celles générées par la requête de vue existante (c'est-à-dire les mêmes noms de colonnes dans le même ordre et avec les mêmes types de données), mais elle peut ajouter des colonnes supplémentaires à la fin de la liste.

Il n'y a aucune raison fondamentale pour laquelle la prise en charge de la suppression de colonnes n'a pas pu être ajoutée, mais personne n'a encore effectué le travail requis pour l'implémenter.

CREATE OR REPLACE VIEWdevrait analyser récursivement toutes les dépendances et s'assurer qu'aucune d'entre elles ne faisait référence à la colonne à supprimer. S'ils l'utilisaient, SELECT *il faudrait supprimer la colonne de l'expansion de *dans la dépendance, puis analyser ses dépendances également. Il y a pas mal de travail à faire pour cela, et il y a des domaines où il n'est pas clair comment exactement la suppression de la colonne doit se comporter, surtout en ce qui concerne les interactions avec le vidage et le rechargement. Donc, personne n'a encore voulu assez de fonctionnalités pour l'implémenter. Les correctifs et / ou le parrainage du développement sont les bienvenus.

Vous devrez supprimer la vue et tout ce qui en dépend, puis la recréer et ses dépendances. (Il en allait de même pour l' ajout d' une colonne à une vue; la prise en charge de l'ajout de colonnes a été introduite en 8.4).

Notez qu'en général, il n'y a aucune attente que DDL soit réversible. Le concept de «dévolutions» est vraiment imparfait. Par exemple, si vous déposez une colonne, puis l'ajoutez à nouveau, les données sont toujours disparues.

Craig Ringer
la source
1
Donc, ce que vous dites, c'est que, chaque fois qu'une grande application avec des relations complexes doit changer une colonne, il est nécessaire de recréer la DDL entière (ou au moins la plus grande partie de) la DDL? Je n'ai pas beaucoup d'expérience avec postgre, mais venant de mySQL, je n'ai jamais eu de problèmes comme ça (avec Oracle, SQL Server ou MySQL), et il me semble étrange que le changement ne puisse pas simplement être fait et des erreurs (si à la place). Cette limitation est assez restrictive.
Yanick Rochon,
@YanickRochon Yep, c'est une douleur, et j'aimerais voir ça s'améliorer. Si vous souhaitez contribuer à ce que cela se produise, envisagez de financer des travaux à ce sujet; voir postgresql.org/support/professional_support .
Craig Ringer du
Nous sommes trop petits pour financer une telle entreprise. Mais content de voir que ce n'est pas un sujet fixe.
Yanick Rochon,
1
@YanickRochon Assez juste. C'est sur le TODO - "autoriser la recompilation des vues / règles lorsque la table sous-jacente change", wiki.postgresql.org/wiki/Todo#Views_and_Rules .
Craig Ringer