Как влияет на идентификатор идентификатора поиска и "текущая схема",

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

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

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

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

Ответ 1

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

% 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

Ответ 2

Каков путь поиска?

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

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

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

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

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

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

Смелый акцент в оригинале. И pg_temp предшествует этому, если он не помещается в другое положение.

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

У вас есть различные опции для фактической установки переменной времени выполнения search_path.

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

    search_path = 'blarg,public'
    

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

    search_path = "$user",public
    

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

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

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

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

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

    SET search_path = blarg,public;
    
  • Задайте конкретный 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;

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

Чтобы просмотреть текущую настройку:

SHOW search_path;

В reset он:

RESET search_path;

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

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