PostgreSQL: soltar columna de la vista

10

Tengo un lugar VIEWdonde intento crear un script de evolución para poder agregarle una columna. Esa parte funciona bien; columna agregada muy bien. Sin embargo, lo contrario no funciona; eliminar esa última columna agregada falla con un ERROR: cannot drop columns from viewmensaje. El problema es que esta visión particular tiene muchas referencias, tanto desde como hacia, por lo tanto, ¡no puedo simplemente DROP CASCADEla maldita cosa!

¿Hay alguna razón por la que no puedo eliminar una columna recién agregada de un determinado VIEW? Entonces, ¿qué puedo hacer para lograr esta tarea?

(Nota: las circunstancias, aquí, son lo que son, pero puedo ver una situación similar, es decir, soltar una columna desde una vista, en muchos otros casos).

Yanick Rochon
fuente
¿Cómo agregaste la columna en primer lugar? No se puede ALTER VIEW ... ADD COLUMN. Estas usando CREATE OR REPLACE VIEW? Muestra tu código por favor.
Craig Ringer
@CraigRinger, sí, CREATE OR REPLACE VIEWcon la misma definición, excepto una columna adicional (porque una tabla refinada tiene una nueva columna agregada, por lo que la vista debe incluirla). La "devolución" elimina la columna de la tabla ref'ed, por lo VIEWque tampoco tiene que devolverla más.
Yanick Rochon

Respuestas:

13

PostgreSQL (verdadero hasta al menos 9.4) actualmente no admite la eliminación de una columna con CREATE OR REPLACE VIEW.

La nueva consulta debe generar las mismas columnas generadas por la consulta de vista existente (es decir, los mismos nombres de columna en el mismo orden y con los mismos tipos de datos), pero puede agregar columnas adicionales al final de la lista.

No hay una razón fundamental por la que no se pueda agregar soporte para soltar columnas, pero nadie ha hecho el trabajo requerido para implementarlo todavía.

CREATE OR REPLACE VIEWtendría que escanear recursivamente todas las dependencias y asegurarse de que ninguna de ellas hiciera referencia a la columna a descartar. Si lo usaran SELECT *, tendría que eliminar la columna de la expansión de *la dependencia y luego escanear sus dependencias también. Hay un poco de trabajo involucrado en hacer eso, y hay algunas áreas en las que no está claro cómo debe comportarse exactamente la caída de la columna, especialmente cuando se trata de interacciones con volcado y recarga. Por lo tanto, nadie quería la función lo suficiente como para implementarla todavía. Los parches y / o patrocinio del desarrollo son bienvenidos.

Tendrá que soltar la vista y todo lo que depende de ella, luego volver a crearla y sus dependencias. (Lo mismo solía ser cierto para agregar una columna a una vista; el soporte para agregar columnas se introdujo en 8.4).

Tenga en cuenta que, en general, no se espera que DDL sea reversible. El concepto de "devoluciones" es realmente defectuoso. Por ejemplo, si suelta una columna y luego la agrega nuevamente, los datos aún no están disponibles.

Craig Ringer
fuente
1
Entonces, lo que está diciendo es que, cuando una aplicación grande con relaciones complejas necesita cambiar una columna, ¿es necesario recrear todo (o al menos la mayor parte) del DDL? No tengo mucha experiencia con Postgre, pero viniendo de mySQL, nunca he tenido problemas como ese (con Oracle, SQL Server o MySQL), y me parece extraño que el cambio no se pueda hacer simplemente y errores (si cualquiera) ser arrojado en tiempo de ejecución en su lugar. Esta limitación es bastante restrictiva.
Yanick Rochon
@ YanickRochon Sí, es un dolor, y me encantaría verlo mejorar. Si desea ayudar a que eso suceda, considere la posibilidad de financiar el trabajo; ver postgresql.org/support/professional_support .
Craig Ringer
Somos demasiado pequeños para financiar una empresa así. Pero me alegra ver que no es un tema fijo.
Yanick Rochon
1
@YanickRochon Bastante justo. Está en TODO - "permitir recompilación de vista / regla cuando la tabla subyacente cambia", wiki.postgresql.org/wiki/Todo#Views_and_Rules .
Craig Ringer