错误:使用Postgres拒绝序列cities_id_seq的权限

我是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。但这并不能解决我的问题。我错过了什么?

249394 次浏览

由于PostgreSQL 8.2,你必须使用:

GRANT USAGE, SELECT ON SEQUENCE cities_id_seq TO www;

GRANT USAGE -对于序列,此特权允许使用curval和nextval函数。

正如@epic_fil在评论中指出的那样,你可以授予模式中所有序列的权限:

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

请注意:不要忘记在执行特权授予命令之前选择数据库(\c <database_name>)

由于@Phil有一个评论获得了很多upvotes,可能不会被注意到,我使用他的语法添加了一个答案,将为一个用户授予一个模式中的所有序列的权限(假设你的模式是默认的“公共”)

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public to www;

@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+。

这将附加到现有的默认权限,而不是覆盖它们,所以在这方面是相当安全的。

在postgres中执行以下命令。

登录postgres:

Sudo su postgres;

psql dbname;

CREATE SEQUENCE public.cities_id_seq . 增量1 < br > MINVALUE 0 < br > MAXVALUE 1 < br > 开始1 缓存1; 更改表公共。

. city_id_seq OWNER TO pgowner

Pgowner将是您的数据库用户。

这是由于在SEQUENCES上的权限问题。

尝试以下命令来解决问题,

GRANT USAGE, SELECT ON SEQUENCE sequence_name TO user_name;

例如:

GRANT USAGE, SELECT ON SEQUENCE cities_id_seq TO www;