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

Vam*_*nik 177 sql postgresql permissions auto-increment

我是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;
Run Code Online (Sandbox Code Playgroud)

当作为用户www尝试:

insert into cities (name) values ('London');
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

ERROR: permission denied for sequence cities_id_seq
Run Code Online (Sandbox Code Playgroud)

我知道问题在于串行类型.这就是为什么我将*_id_seq的选择,插入和删除权限授予www.然而,这并不能解决我的问题.我错过了什么?

kup*_*son 311

从PostgreSQL 8.2开始,你必须使用:

GRANT USAGE, SELECT ON SEQUENCE cities_id_seq TO www;
Run Code Online (Sandbox Code Playgroud)

GRANT USAGE - 对于序列,此权限允许使用currval和nextval函数.

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

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO www;
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,还支持语法"...在SCHEMA schema_name中的所有序列". (50认同)
  • 这怎么回事?我什么时候想要允许用户将数据插入表中但不想让他们使用其中一列自动递增的事实? (32认同)
  • 有趣.我在我的序列所在的桌子上做了一个GRANT,但这似乎不包括序列.这似乎也非常适合操作系统. (4认同)
  • `将schema public中所有序列的所有权限授予staging;` (4认同)
  • 是`SELECT`必要吗?不应该"USAGE"涵盖所需要的内容吗? (4认同)
  • @BrettWidmeier完全正确.让我很难以理解开发人员如何容忍这种事情.这就像人们想要在互联网上漫游并阅读无底的StackOverflow线程,试图解决本应该开箱即用的事情. (4认同)
  • 同样的问题:表上的权限,但不是序列.文档会说_"授予表的权限不会自动将权限扩展到表使用的任何序列,包括绑定到SERIAL列的序列.序列的权限必须单独设置."_(参见[GRANT文档页面].(https ://www.postgresql.org/docs/9.5/static/sql-grant.html)虽然不清楚这是什么问题. (3认同)
  • 从版本 10 开始,您可以指定标识列而不是序列,例如:`id INT GENERATED { ALWAYS | 默认} AS IDENTITY` 所以你不会遇到这个问题 https://www.postgresql.org/docs/10/sql-createtable.html (2认同)

Tom*_*ken 63

由于@Phil有一个评论得到很多可能没有被注意到的upvotes,我正在使用他的语法添加一个答案,它将为一个模式中的所有序列授予用户权限(假设你的模式是默认的'public' )

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public to www;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这仅适用于PostgreSQL 9.0及更高版本,要在8中完成相同的操作,您可以执行以下操作:SELECT'GRANT USAGE,SELECT ON'||| quote_ident(schemaname)|| '' || quote_ident(relname)|| '到www;' FROM pg_statio_all_sequences WHERE schemaname ='public'; - Tom Gerken 2天前 (2认同)

Asf*_*azi 32

@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;
Run Code Online (Sandbox Code Playgroud)

当然,这仅适用于PostgreSQL 9+.

这将附加到现有的默认权限,而不是覆盖它们,因此在这方面非常安全.


Cod*_*ker 5

这是由于序列的权限问题。

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

GRANT USAGE, SELECT ON SEQUENCE sequence_name TO user_name;
Run Code Online (Sandbox Code Playgroud)

例如:

GRANT USAGE, SELECT ON SEQUENCE cities_id_seq TO www;
Run Code Online (Sandbox Code Playgroud)