Как search_path влияет на разрешение идентификатора и «текущую схему» - PullRequest
44 голосов
/ 30 января 2012

Можно ли определить, в какой схеме по умолчанию создаются новые таблицы?(Называется «неквалифицированными именами таблиц».)

Я видел некоторые подробности об использовании «пути поиска» в Postgres, но я думаю, что он работает только при получении данных, но не при их создании.

У меня есть куча SQL-скриптов, которые создают много таблиц.Вместо того, чтобы модифицировать сценарии, я хочу установить базы данных для создания таблиц в определенной схеме по умолчанию - когда они имеют неквалифицированные имена.

Возможно ли это?

Ответы [ 2 ]

69 голосов
/ 30 января 2012

Что такое путь поиска?

По документации:

[...] таблицы часто упоминаются какнеквалифицированные имена, которые состоят только из имени таблицы.Система определяет, какая таблица подразумевается, следуя пути поиска, который представляет собой список схем для поиска в .

Мой жирный шрифт.Это объясняет разрешение идентификатора и «текущая схема» , для документации:

Первая схема с именемв пути поиска называется текущая схема .Помимо поиска первой схемы, это также схема, в которой будут создаваться новые таблицы, если команда CREATE TABLE не задает имя схемы.

Выделение жирным шрифтом.Системные схемы pg_temp (схема для временных объектов текущего сеанса) и pg_catalog автоматически являются частью пути поиска и выполняют поиск first , вэтот заказ. Согласно документации:

pg_catalog всегда эффективно является частью пути поиска.Если он не указан явно в пути, то выполняется неявный поиск перед поиском схем пути.Это гарантирует, что встроенные имена всегда будут доступны для поиска.Однако вы можете явно указать pg_catalog в конце пути поиска, если вы предпочитаете, чтобы определяемые пользователем имена переопределяли встроенные имена.

Выделение жирным шрифтом согласно оригиналу.И pg_temp предшествует этому, если только он не помещен в другое положение.

Как его установить?

У вас есть различные варианты, чтобы фактически установить переменную времени выполнения search_path.

  1. Установить по умолчанию для кластера для всех ролей во всех базах данных в postgresql.conf (и перезагрузить).Осторожно с этим!

    search_path = 'blarg,public'
    

    По умолчанию поставляется для этого параметра :

    search_path = "$user",public
    

    Первый элемент указывает, что схема с тем же именемкак текущий пользователь должен быть найден.Если такой схемы не существует, запись игнорируется.

  2. Установите ее по умолчанию для одной базы данных :

    ALTER DATABASE test SET search_path = blarg,public;
    
  3. Установите его по умолчанию для роли , с которой вы соединяетесь (эффективная для всего кластера):

    ALTER ROLE foo SET search_path = blarg,public;
    
  4. Или даже (часто лучше!)по умолчанию для роли только в данной базе данных :

    ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    
  5. Напишите команду в верхней части вашего скрипта (или выполните ее в любой точке вашей сеанс :

    SET search_path = blarg,public;
    
  6. Установить определенный search_path для области функции (для защиты от злоумышленников с достаточным количествомпривилегии). Читайте о Написание SECURITY DEFINER Функции безопасно в руководстве.

CREATE FUNCTION foo() RETURNS void AS
$func$
BEGIN
   -- do stuff
END
$func$ LANGUAGE plpgsql SECURITY DEFINER
       <b>SET search_path=blarg,public,pg_temp</b>;

Более высокий номер в моем спискеимеет меньшее значение.
В руководстве есть еще больше способов , например, установка переменных среды или использование параметров командной строки.

Чтобы увидеть текущую настройку:

SHOW search_path;

To сброс it:

RESET search_path;

По документации :

Значение по умолчанию определяется как значение, которое будет иметь параметрЕсли в текущем сеансе не было выдано SET, то

27 голосов
/ 30 января 2012

Путь поиска действительно то, что вы хотите:

% 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
...