【问题标题】:ERROR: must be owner of materialized view PostgreSQL错误:必须是物化视图 PostgreSQL 的所有者
【发布时间】:2021-08-04 10:21:43
【问题描述】:

我收到以下错误:

ERROR:  must be owner of materialized view mv_sessions
SQL state: 42501

尝试刷新我的物化视图时:

REFRESH MATERIALIZED VIEW CONCURRENTLY partners.mv_sessions;

mv_sessions 的所有者是我自定义的master 用户。我已将所有权限分配给子用户partner,我正在尝试用它来刷新视图。

我不想让partner 成为mv_sessions 的所有者。还有其他子用户需要能够刷新视图。


我尝试了触发功能:

BEGIN
    REFRESH MATERIALIZED VIEW CONCURRENTLY partners.mv_sessions;
    RETURN NULL;
END 

得到同样的错误:

psycopg2.errors.InsufficientPrivilege: must be owner of materialized view mv_sessions
CONTEXT:  SQL statement "REFRESH MATERIALIZED VIEW CONCURRENTLY partners.mv_sessions"
PL/pgSQL function partners.refresh_mv_sessions() line 3 at SQL statement

我该如何解决这个问题?

【问题讨论】:

  • documentation 确实声明“要执行此命令,您必须是物化视图的所有者”。有关解决方法,请参阅 this answer
  • @Marth 所以我应该创建 3 个相同的 MV,以便能够与 3 个不同的用户访问它们?
  • 没有。读取(访问)权限与刷新权限不同。您可以授予多个用户对同一实体化视图的读取权限,但只有所有者才能触发刷新。或者您可以尝试我链接的答案中的解决方案。

标签: postgresql view materialized-views


【解决方案1】:

导致问题的函数:

CREATE OR REPLACE FUNCTION partners.refresh_mv_sessions()
RETURNS TRIGGER LANGUAGE plpgsql
AS $$
BEGIN
    REFRESH MATERIALIZED VIEW CONCURRENTLY partners.mv_sessions;
    RETURN NULL;
END $$;

根据this answer(Marth 建议)使用SECURITY DEFINER 进行修复,以便非所有者可以刷新物化视图:

CREATE OR REPLACE FUNCTION partners.refresh_mv_sessions()
RETURNS TRIGGER
SECURITY DEFINER
AS $$
BEGIN
    REFRESH MATERIALIZED VIEW CONCURRENTLY partners.mv_sessions;
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

【讨论】:

  • 永远不要在没有SET search_path = ... 的情况下创建SECURITY DEFINER 函数。不过这里碰巧很安全。
  • @LaurenzAlbe 你能详细说明一下search_path吗?
猜你喜欢
  • 2015-04-19
  • 2011-05-21
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多