PostgreSQL: remover coluna da vista

10

Eu tenho um local VIEWonde estou tentando criar um script de evolução para poder adicionar uma coluna a ele. Essa parte funciona bem; coluna adicionada muito bem. No entanto, o inverso não funciona; remova a última coluna adicionada falhará com uma ERROR: cannot drop columns from viewmensagem. O problema é que essa visão em particular tem muitas referências, de e para, portanto, não posso apenas DROP CASCADEo que é danado!

Existe uma razão pela qual não consigo remover uma coluna recém-adicionada de uma determinada VIEW? Então, o que posso fazer para realizar esta tarefa?

(Nota: as circunstâncias, aqui, são o que são, mas posso muito bem ver uma situação semelhante, também conhecida como descartar uma coluna de uma exibição, em muitos outros casos.)

Yanick Rochon
fonte
Como você adicionou a coluna em primeiro lugar? Você não pode ALTER VIEW ... ADD COLUMN. Você está usando CREATE OR REPLACE VIEW? Mostre seu código, por favor.
Craig Ringer
@CraigRinger, sim, CREATE OR REPLACE VIEWcom a mesma definição, exceto uma coluna extra (porque uma tabela refinada possui uma nova coluna adicionada, portanto a visualização precisa incluí-la). A "devolução" remove a coluna da tabela refinada, portanto, VIEWtambém não é mais necessário devolvê-la.
Yanick Rochon

Respostas:

13

O PostgreSQL (verdadeiro até pelo menos 9.4) atualmente não suporta a remoção de uma coluna com CREATE OR REPLACE VIEW.

A nova consulta deve gerar as mesmas colunas que foram geradas pela consulta de exibição existente (ou seja, os mesmos nomes de coluna na mesma ordem e com os mesmos tipos de dados), mas pode adicionar colunas adicionais ao final da lista.

Não há nenhuma razão fundamental pela qual o suporte para descartar colunas não possa ser adicionado, mas ninguém fez o trabalho necessário para implementá-lo ainda.

CREATE OR REPLACE VIEWprecisaria varrer recursivamente todas as dependências e garantir que nenhuma delas referenciasse a coluna a ser eliminada. Se eles usassem SELECT *, teria que remover a coluna da expansão de *na dependência e também varrer suas dependências. Há um bom trabalho envolvido nisso e há algumas áreas em que não está claro como exatamente a queda da coluna deve se comportar, principalmente quando se trata de interações com despejo e recarga. Portanto, ninguém queria o recurso suficiente para implementá-lo ainda. Patches e / ou patrocínio de desenvolvimento são bem-vindos.

Você terá que abandonar a visualização e tudo o que depende dela, depois recrie-a e suas dependências. (O mesmo costumava ser verdadeiro para adicionar uma coluna a uma visualização; o suporte para adicionar colunas foi introduzido na 8.4).

Observe que, em geral, não há expectativa de que o DDL seja reversível. O conceito de "devoluções" é realmente falho. Por exemplo, se você soltar uma coluna e adicioná-la novamente, os dados ainda desaparecerão.

Craig Ringer
fonte
11
Então, o que você está dizendo é que, sempre que um aplicativo grande com relacionamentos complexos precisar alterar uma coluna, é necessário recriar toda a DDL (ou pelo menos a maior parte da) DDL? Eu não tenho muita experiência com o postgre, mas, vindo do mySQL, nunca tive problemas assim (com Oracle, SQL Server ou MySQL), e me parece estranho que a mudança não possa ser feita simplesmente e erros (se any) seja lançada no momento da execução. Essa limitação é bastante restritiva.
Yanick Rochon
@YanickRochon Sim, é uma dor, e eu adoraria vê-la melhorada. Se você quiser ajudar a fazer isso acontecer, considere financiar o trabalho; consulte postgresql.org/support/professional_support .
Craig Ringer
Somos muito pequenos para financiar uma empresa dessas. Mas fico feliz em ver que não é um tópico fixo.
Yanick Rochon
11
@YanickRochon Fair o suficiente. Está no TODO - "permitir recompilação de exibição / regra quando a tabela subjacente mudar", wiki.postgresql.org/wiki/Todo#Views_and_Rules .
Craig Ringer