我想创建新的模式并将公共模式中的表传输到这些模式,但每当我将表从公共模式移动到另一个模式时,对新模式具有使用访问权限的用户/角色,以及它的表(包括未来的表),无法访问新移动的表。
表格(在公开架构中):
CREATE TABLE atable(ID INT);
INSERT INTO atable VALUES(1);
INSERT INTO atable VALUES(2);
新用户:
create user x_user with login password 'x_user';
新架构:
create schema dw;
然后我授予它对新模式及其表的所有访问权限:
GRANT USAGE ON SCHEMA dw TO x_user;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA dw to x_user;
GRANT SELECT ON ALL TABLES IN SCHEMA dw TO x_user;
对于将来添加到架构的表
ALTER DEFAULT PRIVILEGES IN SCHEMA dw GRANT SELECT ON TABLES TO x_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA dw GRANT USAGE ON SEQUENCES TO x_user;
现在我将atable
的架构更改为 dw
:
ALTER TABLE atable SET SCHEMA dw;
另外,我在 dw
架构中创建了另一个表:
CREATE TABLE dw.btable(id int);
INSERT INTO dw.btable VALUES(3);
INSERT INTO dw.btable VALUES(4);
现在,当我使用新用户凭据连接到数据库时,运行:
SELECT * FROM dw.atable;
我得到:ERROR: permission denied for relation atable 1 statement failed.
然而,如果我对 btable
架构中创建的dw
运行相同的查询,则可以正常运行。
SELECT * FROM dw.btable;
id
---
3
4
当我将表从一个模式移动到另一个模式时,它也可以工作,但是当我将表从公共模式移动到另一个模式时,它无效。
我在这里做错了什么?
答案 0 :(得分:1)
GRANT ... ON ALL TABLES IN SCHEMA
仅影响架构的当前内容。
ALTER DEFAULT PRIVILEGES IN SCHEMA
会影响架构中创建的表。
将表从一个模式移动到另一个模式时,这些都没有任何影响,我也不知道有什么用。
应该可以通过创建event trigger来执行此操作,该pg_event_trigger_ddl_commands()
会触发任何ALTER TABLE
命令并应用相应的GRANT
。不幸的是,虽然你可以在PL / pgSQL中编写这些触发器函数,但我认为它(目前)没有提供任何方法来找出实际命令是什么;你需要:
pg_ddl_command
结构
GRANT
之后盲目地运行ALTER TABLE
,无论它是否是SET SCHEMA
命令。一个更简单的选项 - 只要它适合您的用例 - 就是编写一个move_table()
函数,它结合了ALTER
和GRANT
命令。