在PostgreSQL中将模式添加到路径

7
我正在将应用程序从公共模式移动到每个应用程序都有自己的模式。对于每个应用程序,我都有一个小脚本,它将创建模式,然后在该模式下创建表,函数等等...是否有任何方法可以自动将新创建的模式添加到搜索路径中?目前,我唯一看到的方法是找到用户当前路径SHOW search_path;,然后将新模式添加到其中SET search_path to xxx,yyy,zzz; 我希望能够以某种方式将模式zzz附加到用户搜索路径中。这可能吗?
2个回答

17

使用 set_config() 函数,如下所示:

SELECT set_config(
    'search_path',
    current_setting('search_path') || ',zzz',
    false
) WHERE current_setting('search_path') !~ '(^|,)zzz(,|$)';

1
我相信这只会为当前会话设置search_path,并且不会持久化超出该范围。 - Randall
我在使用正则表达式时遇到了麻烦,因为我的路径在逗号后面有一个空格。我改用'(^|,\s?)zzz(,|$)' - ngreen

1

在理论答案的基础上,以下是如何永久性地将模式前缀添加到另一个用户的搜索路径。这对于设置只读用户和将不同模式的设置拆分为不同的.sql文件非常有用。

create or replace function prepend_search_path(
    role_name text, schema_name text
) returns void as $$
declare
    current_search_path text;
begin
    -- First, we get the current search_path for that user
    select  replace(sc.configval,'search_path=','')
    from    pg_db_role_setting rs
    left 
    join    pg_roles r
    on      r.oid = rs.setrole,
    lateral unnest(rs.setconfig) as sc(configval)
    where   sc.configval like 'search_path=%'
    and r.rolname = role_name
    into current_search_path;

    -- It is possible that a new user is not in pg_roles. To fix this,
    -- we find the default search_path values.
    if not found then
        select boot_val
        from pg_settings
        where name='search_path'
        into current_search_path;
    end if;

    -- Prepend the schema_name to search_path
    if current_search_path !~ ('(^|, )' || schema_name || '(,|$)') then
        current_search_path := schema_name || ', ' || current_search_path;
    end if;


    -- Make the changes
    execute format('alter role %I set search_path = %s', role_name, current_search_path);
end
$$ language plpgsql;

为什么要使用prepend?这取决于您的用例。在我看来,为每个存储过程定义模式很有用。这意味着如果您更改了存储过程,只需在单独的模式中定义它并覆盖使用它的用户的search_path即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接