ОШИБКА: отказано в разрешении для последовательности towns_id_seq с использованием Postgres

202

Я новичок в postgres (и вообще в информационных системах баз данных). Я запустил следующий скрипт SQL в моей базе данных:

create table cities (
id serial primary key,
name text not null
);

create table reports (
id serial primary key,
cityid integer not null references cities(id),
reportdate date not null,
reporttext text not null
);

create user www with password 'www';

grant select on cities to www;
grant insert on cities to www;
grant delete on cities to www;

grant select on reports to www;
grant insert on reports to www;
grant delete on reports to www;

grant select on cities_id_seq to www;
grant insert on cities_id_seq to www;
grant delete on cities_id_seq to www;

grant select on reports_id_seq to www;
grant insert on reports_id_seq to www;
grant delete on reports_id_seq to www;

Когда, как пользователь www, пытаюсь:

insert into cities (name) values ('London');

Я получаю следующую ошибку:

ERROR: permission denied for sequence cities_id_seq

Я понимаю, что проблема заключается в серийном типе. Вот почему я даю права на выбор, вставку и удаление для * _id_seq на www. Но это не решает мою проблему. Чего мне не хватает?

Vampnik
источник
2
Предоставление вставки / удаления последовательности не имеет смысла для меня. Я удивлен, что это даже работает.
a_horse_with_no_name

Ответы:

360

Начиная с PostgreSQL 8.2 вы должны использовать:

GRANT USAGE, SELECT ON SEQUENCE cities_id_seq TO www;

GRANT USAGE - для последовательностей эта привилегия позволяет использовать функции currval и nextval.

Также, как указано @epic_fil в комментариях, вы можете предоставить разрешения для всех последовательностей в схеме с помощью:

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO www;
kupson
источник
52
К вашему сведению, синтаксис "... НА ВСЕХ ПОСЛЕДОВАТЕЛЬНОСТЯХ В СХЕМЕ schema_name" также поддерживается.
epic_fil
5
Интересный. Я сделал GRANT все на столе, в котором находится моя последовательность, но это, кажется, не покрывает последовательность. Это тоже кажется самой ОС.
Киннард Хоккенхалл
42
Как это реально? Когда я захочу разрешить пользователю вставлять данные в таблицу, но НЕ хочу, чтобы он использовал тот факт, что один из столбцов является автоинкрементным?
Бретт Видмейер
5
IS SELECTнеобходимо? Не должны USAGEохватывать то, что нужно?
Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ
7
@BrettWidmeier Точно. Меня ошеломляет, как разработчики допускают подобные вещи. Как будто люди хотят бродить по Интернету и читать бездонные потоки StackOverflow, пытаясь исправить вещи, которые должны были работать прямо из коробки.
milosmns
67

Поскольку у @Phil есть комментарий, который вызывает много положительных отзывов, которые могут быть не замечены, я использую его синтаксис, чтобы добавить ответ, который предоставит пользователю разрешения для всех последовательностей в схеме (при условии, что ваша схема по умолчанию является общедоступной). )

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public to www;
Том Геркен
источник
2
Обратите внимание, что это работает только в PostgreSQL 9.0 и выше, чтобы выполнить то же самое в 8, вы можете сделать что-то вроде: SELECT 'GRANT USAGE, SELECT ON' || quote_ident (schemaname) || '' || quote_ident (relname) || 'TO www;' FROM pg_statio_all_sequence WHERE schemaname = 'public'; - Том Геркен, 2 дня назад
Том Геркен,
39

@Tom_Gerken, @epic_fil и @kupson вполне корректны в своих утверждениях, чтобы дать разрешения для работы с существующими последовательностями. Однако пользователь НЕ получит права доступа к последовательностям, созданным в будущем. Для этого вам нужно объединить оператор GRANT с оператором ALTER DEFAULT PRIVILEGES, например, так:

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO www;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT USAGE, SELECT ON SEQUENCES TO www;

Конечно, это работает только на PostgreSQL 9+.

Это добавит к существующим привилегиям по умолчанию, а не перезапишет их, поэтому вполне безопасно в этом отношении.

Асфанд Кази
источник
-2

Выполните следующую команду в postgres.

войти в postgres:

судо су постгрес;

psql dbname;

CREATE SEQUENCE public.cities_id_seq INCREMENT 1
MINVALUE 0
MAXVALUE 1
START 1 CACHE 1; ALTER TABLE public.cities_id_seq ВЛАДЕЛЕЦ pgowner;

pgowner будет вашим пользователем базы данных.

Shreeram
источник