PostgreSQL: elimina la colonna dalla vista


10

Ho un punto in VIEWcui sto tentando di creare uno script di evoluzione, quindi posso aggiungere una colonna ad esso. Quella parte funziona benissimo; colonna aggiunta bene. Tuttavia, il contrario non funziona; rimuovere l'ultima colonna aggiunta non riesce con un ERROR: cannot drop columns from viewmessaggio. Il problema è che questa particolare visione ha molti riferimenti, sia da che verso, quindi non posso proprio fare DROP CASCADEla cosa maledetta!

C'è un motivo per cui non riesco a rimuovere una colonna appena aggiunta da un dato VIEW? Quindi, cosa posso fare per svolgere questo compito?

(Nota: le circostanze, qui, sono quelle che sono, ma riesco benissimo a vedere una situazione simile, ovvero far cadere una colonna da una vista, in molti altri casi.)


Come hai aggiunto la colonna in primo luogo? Non puoi ALTER VIEW ... ADD COLUMN. Stai usando CREATE OR REPLACE VIEW? Mostra il tuo codice per favore.
Craig Ringer,

@CraigRinger, sì, CREATE OR REPLACE VIEWcon la stessa def, tranne una colonna aggiuntiva (perché una tabella ref'ed ha una nuova colonna aggiunta, quindi la vista deve includerla). La "devolution" rimuove la colonna dalla tabella ref'ed, in modo che il VIEWdeve anche non tornare più.
Yanick Rochon,

Risposte:


13

PostgreSQL (vero fino ad almeno 9.4) attualmente non supporta la rimozione di una colonna con CREATE OR REPLACE VIEW.

La nuova query deve generare le stesse colonne generate dalla query di visualizzazione esistente (ovvero gli stessi nomi di colonna nello stesso ordine e con gli stessi tipi di dati), ma può aggiungere colonne aggiuntive alla fine dell'elenco.

Non vi è alcun motivo fondamentale per cui non sia possibile aggiungere il supporto per l'eliminazione delle colonne, ma nessuno ha ancora svolto il lavoro necessario per implementarlo.

CREATE OR REPLACE VIEWdovrebbe eseguire una scansione ricorsiva di tutte le dipendenze e assicurarsi che nessuna di esse faccia riferimento alla colonna da eliminare. Se lo avessero usato SELECT *, avrebbe dovuto rimuovere la colonna dall'espansione della *dipendenza, quindi scansionare anche le sue dipendenze. C'è un bel po 'di lavoro coinvolto nel farlo, e ci sono alcune aree in cui non è chiaro come dovrebbe comportarsi esattamente la caduta della colonna, specialmente quando si tratta di interazioni con il dump e il ricaricamento. Quindi nessuno ha voluto la funzionalità abbastanza per implementarla ancora. Patch e / o sponsorizzazioni di sviluppo sono benvenute.

Dovrai rilasciare la vista e tutto ciò che dipende da essa, quindi ricrearla e le sue dipendenze. (Lo stesso valeva per l' aggiunta di una colonna a una vista; il supporto per l'aggiunta di colonne è stato introdotto in 8.4).

Si noti che in generale non si prevede che il DDL sia reversibile. Il concetto di "devoluzioni" è davvero imperfetto. Ad esempio, se si elimina una colonna, quindi la si aggiunge di nuovo, i dati spariranno comunque.


1
Quindi, quello che stai dicendo è che, ogni volta che un'applicazione di grandi dimensioni con relazioni complesse deve cambiare una colonna, è necessario ricreare l'intero (o almeno la maggior parte del) DDL? Non ho molta esperienza con Postgre, ma provenendo da mySQL, non ho mai avuto problemi del genere (con Oracle, SQL Server o MySQL) e mi sembra strano che la modifica non possa essere semplicemente fatta ed errori (se qualsiasi) essere lanciato al momento dell'esecuzione. Questa limitazione è abbastanza restrittiva.
Yanick Rochon,

@YanickRochon Sì, è un dolore, e mi piacerebbe vederlo migliorato. Se desideri contribuire a far sì che ciò accada, prendi in considerazione il finanziamento del lavoro su di esso; vedi postgresql.org/support/professional_support .
Craig Ringer,

Siamo troppo piccoli per finanziare una simile impresa. Ma felice di vedere che non è un argomento fisso.
Yanick Rochon,

1
@YanickRochon Abbastanza giusto. È su TODO - "consentire la ricompilazione di view / rule quando la tabella sottostante cambia", wiki.postgresql.org/wiki/Todo#Views_and_Rules .
Craig Ringer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.