Изменение search_path PostgreSQL не работает так, как рекламируется

Я использую PostgreSQL 9.0.3 на RedHat. База данных содержит две схемы, public и wh. Я создал новую роль под названием django. Я хочу, чтобы этот пользователь использовал схему wh по умолчанию.

По мануалу сделал:

ALTER USER django SET SEARCH_PATH TO wh, public;

Похоже, это работает:

SHOW SEARCH_PATH;
search_path 
-------------
wh, public

Однако, если я затем выполню \dt, отобразятся только таблицы из общедоступной схемы. В руководстве изменение пути поиска должно иметь немедленный эффект, и я должен иметь доступ к wh таблицам без префикса, но это не так. При входе и выходе изменения в search_path сохраняются, но никаких изменений в поведении не наблюдается.

Что мне не хватает?


person talonsensei    schedule 13.09.2011    source источник


Ответы (5)


GRANT может решить вашу проблему:

GRANT USAGE ON SCHEMA wh TO django;

(Или GRANT USAGE ... для любой роли, в которой django является членом (прямым или косвенным).)
(Или GRANT ALL ..., если вы этого хотите.)

Установка search_path указывает Postgres искать объекты в перечисленных схемах. Он не дает разрешения посмотреть, что там. Если у django нет необходимых привилегий, \dt не должен (и не показывает) эту информацию.

С другой стороны, если вы уже пробовали как суперпользователь (согласно вашему комментарию к предыдущему предложению), то это может быть не так...

person Erwin Brandstetter    schedule 14.09.2011
comment
Привет, Эрвин, это сработало! Мне очень странно, что предоставление суперпользователя этой роли не выполнило этого. Однако явное предоставление схемы делает поведение правильным. Большое спасибо и спасибо всем, кто внес свой вклад. - person talonsensei; 14.09.2011
comment
При запросе таблицы без квалификации схемы, такой как SELECT id FROM mytable, PG скажет relation "mytable" does not exists, что немного вводит в заблуждение, поскольку вы знаете, что она существует, но, возможно, у вас просто нет доступа. Поэтому, когда вы запрашиваете таблицу с правильно определенным именем схемы, таким как SELECT id FROM myschema.mytable;, вместо этого вы получите сообщение: permission denied for schema .., которое ясно указывает на необходимость оператора GRANT USAGE ON SCHEMA ... Это еще одна причина, почему использование полных имен схем в запросах является хорошей идеей. - person StartupGuy; 26.10.2013
comment
Эй, Эрвин, спасибо за решение, ты спас меня! :-) и спасибо talonsensei за то, что он инициировал вопрос здесь :-) - person shahjapan; 07.11.2014

Я только что протестировал его (только выпуски) 9.1 в 64-разрядной версии Windows, и он работал, как указано.

Выдержка из справочной страницы ALTER ROLE:

Остальные варианты изменяют значение сеанса роли по умолчанию для переменной конфигурации либо для всех баз данных, либо, если указано предложение IN DATABASE, только для сеансов в указанной базе данных. Всякий раз, когда роль впоследствии запускает новый сеанс, указанное значение становится значением по умолчанию для сеанса, переопределяя любой параметр, присутствующий в postgresql.conf или полученный из командной строки postgres. Это происходит только во время входа в систему; выполнение SET ROLE или SET SESSION AUTHORIZATION не приводит к установке новых значений конфигурации.

(выделено мной)

person Milen A. Radev    schedule 13.09.2011
comment
Спасибо Милен. Я сделал это. Это работает с ролью основного администратора/суперпользователя, и \dt будет отображать таблицы только в схеме wh. Однако по непонятной мне причине, когда я делаю это для другого пользователя, даже если я сделал их также администратором/суперпользователем, \dt по-прежнему показывает только общедоступные таблицы, а не wh, даже если путь изменен. - person talonsensei; 14.09.2011
comment
Если бы вы могли надежно воспроизвести это и разработать небольшой тестовый пример, я думаю, разработчики захотят услышать от вас. Но сначала вы должны убедиться, что тестируете/воспроизводите это в последней младшей версии (9.0.4) основной версии, которую вы используете (9.0). - person Milen A. Radev; 14.09.2011
comment
Спасибо Милен. Я считаю, что это воспроизводимо. Я тестировал обе версии: 9.0.1 (Snow Leopard) и 9.0.3 (Redhat). - person talonsensei; 14.09.2011

Это может быть ограничение команды \dt.

Чтобы убедиться, что search_path работает правильно, попробуйте запустить SELECT * FROM some_table, где some_table — это тот, который находится в схеме wh.

person a_horse_with_no_name    schedule 13.09.2011
comment
Спасибо за предложение. Я пробовал это, но получаю сообщение об ошибке, говорящее, что таблица не существует. Если я добавлю к запросу префикс wh, он сработает. Так что это не похоже на ограничение \dt - person talonsensei; 14.09.2011

Для PostgreSQL, если пользователь подключается к базе данных и ищет такие объекты, как таблица, сначала он будет искать схему так же, как то же имя имени пользователя, если не найдено, он будет искать общедоступную схему. В вашем случае, если вы подключите базу данных через пользователя django, по умолчанию она будет искать схему django, но вы хотите, чтобы текущая схема была wh, поэтому сделайте имя схемы и имя роли одинаковыми, а затем войдите в базу данных, так как роль решит вашу проблему , не вводя префикс, просто попробуйте!

person francs    schedule 14.09.2011
comment
Привет, Франкс, Ваше предложение имеет смысл, и я попробовал его, но пространством поиска по умолчанию для пользователя wh по-прежнему является $user,public, а \dt по-прежнему показывает только общедоступные таблицы. Результатом current_schemas(true) является {pg_catalog,public}. Так что это не работает. - person talonsensei; 14.09.2011
comment
Теперь, каково ваше имя пользователя и имя схемы? если база данных не является prod db, вы можете сделать их одинаковыми. А также обратите внимание на имя владельца таблицы. - person francs; 15.09.2011

Для меня проблема заключалась в том, что я пытался установить путь поиска в pgAdmin. По какой-то причине он не применял изменения к search_path. (Он продолжал задавать параметры в базе данных?)
Я вошел в систему через psql и выполнил те же самые команды, и это сработало. Может быть, я сделал что-то не так, но это может помочь другим, если они тоже делают что-то не так :)

person smithygreg    schedule 16.04.2018