web-dev-qa-db-ja.com

Postgresのマテリアライズドビューを置き換える

新しい列で更新するマテリアライズドビューをPostgres 9.3に持っています。ただし、他のマテリアライズドビューもこのビューに依存しており、エラーメッセージは、他のオブジェクトがビューに依存している場合はビューを削除できないことを示しています。

エラー:他のオブジェクトがマテリアライズドビューに依存しているため、マテリアライズドビューlatest_chargesを削除できません

また、REPLACEキーワードはマテリアライズドビューに対して有効ではないようです。すべての依存オブジェクトを削除してそれぞれを再構築する以外に、ショートカットはありますか?

25
John

PostgreSQL 9.4現在: CREATE VIEWのドキュメント とは異なり、 CREATE MATERIALIZED VIEW のドキュメントではREPLACEキーワードについて言及していません。すべての依存オブジェクトを削除して、それぞれを再構築する以外にショートカットはないようです。

あなたがそうするとき、私は2つの小さなことしか推薦できません:

  1. DROP MATERIALIZED VIEW blabla CASCADEを使用して、すべての依存オブジェクトのリストを取得します
  2. すべての依存オブジェクトの削除と再作成を1つのトランザクションで実行します。
17
alfonx

私の状況では、ビューレイヤーを使用してドロップを制限することを好みます。

  1. 「_new」という接尾辞が付いたマテリアライズドビューのコピーを作成し、パフォーマンスのために「WITH NO DATA」も使用してください。また、DROP ... CASCADEによって検出された接尾辞とその他の依存オブジェクトを使用してインデックスが作成されていることを確認してください
  2. 抽象化のレイヤーを提供するために、新しいマテリアライズドビューにビューを作成しますので、1か所で変更するだけで済みます
  3. 既存の依存関係を変更して、代わりに新しいビューを参照します(事前に必要に応じてデータを更新します)。
  4. 従属関係を持たないはずの元のマテリアライズドビューとインデックスを削除します
  5. マテリアライズドビューとインデックスを変更して、サフィックスを削除して元の名前を復元します

例えば。

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
5
RuiDC

PgAdmin(バージョン4.x)では、プロパティボックスの定義(where句を追加)を簡単に変更できました。あなたの問題はその方法で解決できます。

1
user2953022