Zamień zmaterializowany widok w Postgres

23

Mam zmaterializowany widok, w Postgres 9.3którym chciałbym zaktualizować o nowe kolumny. Jednak inne zmaterializowane widoki również zależą od tego widoku, a komunikat o błędzie wskazuje, że upuszczenie widoku nie jest możliwe, gdy inne obiekty zależą od niego.

BŁĄD: nie można upuścić widoku zmaterializowanego ostatnie_ładowania, ponieważ zależą od niego inne obiekty

Z dokumentacji wynika również, że słowo kluczowe REPLACE jest nieprawidłowe dla zmaterializowanego widoku. Czy istnieje jakiś skrót oprócz upuszczania wszystkich zależnych obiektów i przebudowywania każdego z nich?

Jan
źródło
7
Niestety myślę, że utknąłeś z upuszczeniem ich wszystkich i odbudowaniem.
Craig Ringer
@CraigRinger zainteresowany dodaniem tego jako odpowiedzi?
dezso

Odpowiedzi:

17

Począwszy od PostgreSQL 9.4: W odróżnieniu od dokumentacji CREATE VIEW , dokumentacja CREATE MATERIALIZED VIEW NIE wspomina słowa kluczowego REPLACE. Wydaje się, że nie ma skrótu oprócz upuszczania wszystkich zależnych obiektów i przebudowywania każdego z nich.

Gdy to zrobisz, mogę polecić tylko dwie małe rzeczy:

  1. Użyj DROP MATERIALIZED VIEW blabla CASCADE, aby uzyskać listę wszystkich zależnych obiektów
  2. Wykonaj upuszczenie i odtworzenie wszystkich zależnych obiektów w jednej transakcji.
alfonx
źródło
1
Dzięki, właśnie tak to robiłem. Trudno jest zachować prostotę, ponieważ buduję jeden podstawowy zmaterializowany widok do celów analitycznych, który jest ponownie wykorzystywany w wielu innych widokach. Ten widok podstawowy rzadko się zmienia, ale te, które od niego zależą, zmieniają się codziennie.
John
4

W mojej sytuacji wolę ograniczyć upuszczanie za pomocą warstwy widoku:

  1. Utwórz kopię zmaterializowanego widoku z sufiksem „_new”, a także użyj „BEZ DANYCH” w celu zwiększenia wydajności, upewnij się, że wszystkie indeksy są również tworzone z sufiksem i innymi zależnymi obiektami wykrytymi przez DROP ... CASCADE
  2. Utwórz widok na nowym zmaterializowanym widoku, aby zapewnić warstwę abstrakcji, więc muszę go zmienić tylko w jednym miejscu
  3. ZMIEŃ istniejące zależności, aby zamiast tego odwoływać się do nowego widoku (w razie potrzeby odśwież dane wcześniej)
  4. Upuść oryginalny zmaterializowany widok i indeksy, które nie powinny mieć żadnych zależności
  5. ZMIEŃ zmaterializowany widok i indeksy, aby upuścić sufiks w celu przywrócenia oryginalnych nazw

na przykład.

create table test (myfield int);
insert into test values (1);
create materialized view mv_test as select myfield from test;
create view v_test as select myfield from mv_test;
select * from v_test;
create materialized view mv_test_new as select myfield, myfield+1 as myfield2 from test;
alter view v_test rename to v_test_old;
alter materialized view mv_test rename to mv_test_old;
create view v_test as select myfield,myfield2 from mv_test_new;
select * from v_test;
alter materialized view mv_test_new rename to mv_test;
drop view v_test_old; -- when ready
drop materialized view mv_test_old; -- when ready
RuiDC
źródło
Nie rozumiem tych dwóch ostatnich kroków. Czy 4 zdanie zaczyna się na 5? czy możesz zrobić szybki przykład z niektórymi nazwanymi widokami i widokami mat?
kimbo305,
poprawiono skrócone zdanie i dodano przykład
RuiDC
1

W PgAdmin (wersja 4.x) mogłem łatwo zmodyfikować definicję (dodałem klauzulę where) w polu właściwości. Twój problem można rozwiązać w ten sposób.

użytkownik2953022
źródło