search_path如何影响标识符解析和"当前架构"

thy*_*oso 46 postgresql schema search-path database-table

是否可以定义默认情况下创建新表的模式?(由"不合格的表名称"引用.)

我已经看到了在Postgres中使用"搜索路径"的一些细节,但我认为它只在检索数据时有效,而不是创建.

我有一堆SQL脚本,它们创建了许多表.我没有修改脚本,而是希望默认情况下在特定模式中设置数据库创建表 - 当它们具有非限定名称时.

这可能吗?

Erw*_*ter 72

什么是搜索路径?

每个文件:

[...]表通常由非限定名称引用,这些名称仅包含表名.系统通过遵循搜索路径来确定表示哪个表,搜索路径是要查看的模式列表.

大胆强调我的.这解释了标识符解析,并且"当前模式"每个文档:

搜索路径中命名第一个模式称为当前模式.除了是第一个搜索的模式之外,如果CREATE TABLE命令未指定模式名称,它也是将在其中创建新表的模式.

大胆强调我的.系统模式pg_temp(当前会话的临时对象的模式)并pg_catalog自动成为搜索路径的一部分,并按此顺序首先进行搜索.每个文件:

pg_catalog始终是搜索路径的有效组成部分.如果未在路径中明确命名,则 搜索路径的模式之前会隐式搜索它.这可确保始终可以找到内置名称.但是,pg_catalog如果您希望使用用户定义的名称覆盖内置名称,则可以显式放置在搜索路径的末尾.

根据原件大胆强调.和pg_temp之前出现,除非它置入一个不同的位置.

怎么设置呢?

您可以使用各种选项来实际设置运行时变量search_path.

  1. 为(并重新加载)中的所有数据库中的所有角色设置群集范围的默认值postgresql.conf.小心!

    search_path = 'blarg,public'
    
    Run Code Online (Sandbox Code Playgroud)

    此设置出厂默认值为:

    search_path = "$user",public
    
    Run Code Online (Sandbox Code Playgroud)

    第一个元素指定要搜索与当前用户同名的模式.如果不存在此类模式,则忽略该条目.

  2. 将其设置为一个数据库的默认值:

    ALTER DATABASE test SET search_path = blarg,public;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 将其设置为您连接的角色的默认值(有效的群集范围):

    ALTER ROLE foo SET search_path = blarg,public;
    
    Run Code Online (Sandbox Code Playgroud)
  4. 或者甚至(通常最好!)作为仅在给定数据库中角色的默认值:

    ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    
    Run Code Online (Sandbox Code Playgroud)
  5. 将命令写在脚本的顶部(或者在会话中的任何位置执行它:

    SET search_path = blarg,public;
    
    Run Code Online (Sandbox Code Playgroud)
  6. 设置特定search_path功能范围(以保护具有足够权限的恶意用户).请阅读手册中的安全编写SECURITY DEFINER功能.

CREATE FUNCTION foo() RETURNS void AS
$func$
BEGIN
   -- do stuff
END
$func$ LANGUAGE plpgsql SECURITY DEFINER
       SET search_path=blarg,public,pg_temp;
Run Code Online (Sandbox Code Playgroud)

我的列表中较高的数字胜过较低的数字.
手册有更多的方式,比如设置环境变量或使用命令行选项.

要查看当前设置:

SHOW search_path;
Run Code Online (Sandbox Code Playgroud)

重置它:

RESET search_path;
Run Code Online (Sandbox Code Playgroud)

每个文件:

默认值定义为参数将具有的值,如果SET在当前会话中没有为其发出过该值.


Ale*_*sky 28

搜索路径确实是你想要的:

% create schema blarg;
% set search_path to blarg;
% create table foo (id int);
% \d
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 blarg  | foo  | table | pgsql
Run Code Online (Sandbox Code Playgroud)

  • 您应该能够在配置文件中设置search_path参数,或者通过以下方式使用户永久保存:ALTER USER <user> SET search_path = whatever; (2认同)
  • 您还可以将其设置为数据库的默认值:`ALTER DATABASE db SET search_path = ...` 甚至对于特定的用户/数据库组合(在 9.1 上):`ALTER ROLE user IN DATABASE db SET search_path = ...` ,但是如果您过多地使用这些设置,它们可能会导致混淆,请注意,它们何时被转储尚不清楚。 (2认同)