PostgreSQL: usuń kolumnę z widoku

10

Mam miejsce, w VIEWktórym próbuję utworzyć skrypt ewolucji, więc mogę dodać do niego kolumnę. Ta część działa dobrze; kolumna dodana dobrze. Jednak odwrotna sytuacja nie działa; usuń ostatnią dodaną kolumnę z ERROR: cannot drop columns from viewkomunikatem. Problem polega na tym, że ten konkretny pogląd ma wiele odniesień, zarówno od, jak i do, dlatego nie mogę po prostu DROP CASCADEtego cholerstwa!

Czy istnieje powód, dla którego nie mogę usunąć nowo dodanej kolumny z danego VIEW? Co zatem mogę zrobić, aby wykonać to zadanie?

(Uwaga: okoliczności są tutaj takie, jakie są, ale bardzo dobrze widzę podobną sytuację, czyli w wielu przypadkach wypadanie kolumny z widoku).

Yanick Rochon
źródło
Jak w pierwszej kolejności dodałeś kolumnę? Nie możesz ALTER VIEW ... ADD COLUMN. Używasz CREATE OR REPLACE VIEW? Pokaż proszę swój kod .
Craig Ringer,
@CraigRinger, tak, CREATE OR REPLACE VIEWz tym samym def, z wyjątkiem dodatkowej kolumny (ponieważ w tabeli ref'ed dodano nową kolumnę, więc widok musi ją uwzględnić). W „decentralizacja” usuwa kolumnę z ref'ed tabeli, więc VIEWmusi też nie zwracać go już.
Yanick Rochon,

Odpowiedzi:

13

PostgreSQL (prawda do co najmniej 9,4) nie obsługuje obecnie usuwania kolumny z CREATE OR REPLACE VIEW.

Nowe zapytanie musi wygenerować te same kolumny, które zostały wygenerowane przez istniejące zapytanie widoku (to znaczy te same nazwy kolumn w tej samej kolejności i z tymi samymi typami danych), ale może dodać dodatkowe kolumny na końcu listy.

Nie ma podstawowego powodu, dla którego nie można dodać obsługi usuwania kolumn, ale nikt jeszcze nie wykonał pracy wymaganej do jej wdrożenia.

CREATE OR REPLACE VIEWmusiałby rekurencyjnie skanować wszystkie zależności i upewnić się, że żadna z nich nie odwołuje się do kolumny, która ma zostać usunięta. Gdyby ich użyli SELECT *, musiałby usunąć kolumnę z rozszerzenia *zależności, a następnie zeskanować również jej zależności. Jest przy tym sporo pracy i jest kilka obszarów, w których nie jest jasne, jak dokładnie powinno zachowywać się upuszczanie kolumny, szczególnie jeśli chodzi o interakcje z zrzutem i przeładowaniem. Więc nikt nie chciał tej funkcji na tyle, aby ją wdrożyć. Poprawki i / lub sponsoring rozwoju są mile widziane.

Musisz upuścić widok i wszystko, co od niego zależy, a następnie ponownie go utworzyć i jego zależności. (Tak samo było w przypadku dodawania kolumny do widoku; obsługę dodawania kolumn wprowadzono w 8.4).

Zauważ, że ogólnie nie oczekuje się, że DDL będzie odwracalne. Pojęcie „dewolucji” jest naprawdę błędne. Na przykład, jeśli upuścisz kolumnę, a następnie dodasz ją ponownie, danych nadal nie ma.

Craig Ringer
źródło
2
Mówisz więc, że za każdym razem, gdy duża aplikacja ze złożonymi relacjami musi zmienić kolumnę, konieczne jest odtworzenie całego (lub przynajmniej większości) DDL? Nie mam dużego doświadczenia z postgre, ale pochodzę z mySQL, nigdy nie miałem takich problemów (z Oracle, SQL Server lub MySQL) i wydaje mi się dziwne, że zmiany nie można po prostu zrobić i błędów (jeśli dowolny) zamiast tego zostanie wyrzucony w czasie wykonywania. To ograniczenie jest dość restrykcyjne.
Yanick Rochon,
@YanickRochon Tak, to ból, a ja chciałbym, żeby to się poprawiło. Jeśli chcesz pomóc, aby tak się stało, rozważ finansowanie nad tym; patrz postgresql.org/support/professional_support .
Craig Ringer,
Jesteśmy zbyt mali, aby sfinansować takie przedsięwzięcie. Ale cieszę się, że to nie jest ustalony temat.
Yanick Rochon
1
@YanickRochon Fair Fair. Jest w TODO - „zezwól na rekompilację widoku / reguły, gdy zmieni się podstawowa tabela”, wiki.postgresql.org/wiki/Todo#Views_and_Rules .
Craig Ringer