在Postgres中替换实例化视图


23

我有一个物化视图Postgres 9.3,我想用新的列进行更新。但是,其他实例化视图也依赖于此视图,并且错误消息表明,当其他对象依赖该视图时,则无法删除该视图。

错误:无法删除实例化视图latest_charges,因为其他对象依赖它

从文档中还可以看出,REPLACE关键字对于实例化视图无效。除了删除所有依赖对象并重建每个依赖对象之外,还有没有捷径可走?


7
可悲的是,我认为您一直坚持将它们全部删除并进行重建。
Craig Ringer 2014年

@CraigRinger有兴趣将此添加为答案吗?
dezso 2014年

Answers:


17

从PostgreSQL 9.4开始:与CREATE VIEW的文档不同,CREATE MATERIALIZED VIEW的文档没有提及REPLACE关键字。除了删除所有依赖对象并重建每个对象之外,似乎没有捷径可走。

当您这样做时,我只能推荐两个小事项:

  1. 使用DROP MATERIALIZED VIEW blabla CASCADE获取所有依赖对象的列表
  2. 在一个事务中删除和重新创建所有相关对象。

1
谢谢,这正是我一直在做的事情。保持直截了当只是痛苦,因为我正在建立一个用于分析目的的基本物化视图,并在许多其他视图中重复使用。该基本视图很少更改,但是依赖它的视图每天都在更改。
约翰

4

对于我的情况,我更喜欢通过使用视图层来限制放置:

  1. 创建后缀为“ _new”的实例化视图的副本,并使用“ WITH NO DATA”提高性能,确保还创建了带有后缀的任何索引以及通过DROP ... CASCADE发现的任何其他相关对象
  2. 在新的实体化视图上创建一个视图以提供抽象层,因此我只需要在一个地方进行更改
  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

我不清楚最后两个步骤。是4句话变成5吗?你能用一些命名的matview和视图做一个简单的例子吗?
kimbo305 '18

更正了被删节的句子并添加了示例
RuiDC '18

1

在PgAdmin(版本4.x)中,我可以轻松地在属性框中修改定义(添加了where子句)。您的问题可以通过这种方式解决。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.