我想在PostgreSQL中创建一个用户,只能从特定的数据库中进行select。在MySQL中,命令是:

GRANT SELECT ON mydb.* TO 'xxx'@'%' IDENTIFIED BY 'yyy';

PostgreSQL中等价的命令或命令系列是什么?

我试着…

postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy';
postgres=# GRANT SELECT ON DATABASE mydb TO xxx;

但是,似乎您可以在数据库上授予的权限只有CREATE、CONNECT、TEMPORARY和TEMP。


当前回答

从PostgreSQL v14开始,你可以通过授予预定义的pg_read_all_data角色来实现:

GRANT pg_read_all_data TO xxx;

其他回答

不直接的方法是在数据库的每个表上授权选择:

postgres=# grant select on db_name.table_name to read_only_user;

您可以通过从数据库元数据生成授权语句来实现自动化。

CREATE USER username SUPERUSER  password 'userpass';
ALTER USER username set default_transaction_read_only = on;

参考本博客:

创建只读用户脚本:

CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234' 
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity';
\connect YourDatabaseName;

为该只读用户分配权限:

GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User;
GRANT USAGE ON SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User;
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

分配权限以读取将来创建的所有新表

ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User;

将使用/选择授权给单个表

如果只向数据库授予CONNECT权限,则该用户可以连接,但没有其他特权。你必须在命名空间(模式)上授予USAGE,在表和视图上分别授予SELECT,如下所示:

GRANT CONNECT ON DATABASE mydb TO xxx;
-- This assumes you're actually connected to mydb..
GRANT USAGE ON SCHEMA public TO xxx;
GRANT SELECT ON mytable TO xxx;

多表/视图(PostgreSQL 9.0+)

在最新版本的PostgreSQL中,你可以使用一个命令来授予模式中所有表/视图/等等的权限,而不必一个一个地键入它们:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;

这只影响已经创建的表。更强大的是,你可以自动将默认角色分配给未来的新对象:

ALTER DEFAULT PRIVILEGES IN SCHEMA public
   GRANT SELECT ON TABLES TO xxx;

Note that by default this will only affect objects (tables) created by the user that issued this command: although it can also be set on any role that the issuing user is a member of. However, you don't pick up default privileges for all roles you're a member of when creating new objects... so there's still some faffing around. If you adopt the approach that a database has an owning role, and schema changes are performed as that owning role, then you should assign default privileges to that owning role. IMHO this is all a bit confusing and you may need to experiment to come up with a functional workflow.

多个表/视图(PostgreSQL 9.0之前版本)

为了避免在冗长的多表更改中出现错误,建议使用以下“自动”过程为每个表/视图生成所需的GRANT SELECT:

SELECT 'GRANT SELECT ON ' || relname || ' TO xxx;'
FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
WHERE nspname = 'public' AND relkind IN ('r', 'v', 'S');

这应该在公共的所有表、视图和序列上输出相关的GRANT命令到GRANT SELECT,以实现复制-粘贴。当然,这将只应用于已经创建的表。

如果您的数据库在公共模式中,这很容易(假设您已经创建了readonlyuser)

db=> GRANT SELECT ON ALL TABLES IN SCHEMA public to readonlyuser;
GRANT
db=> GRANT CONNECT ON DATABASE mydatabase to readonlyuser;
GRANT
db=> GRANT SELECT ON ALL SEQUENCES IN SCHEMA public to readonlyuser;
GRANT

如果你的数据库使用customschema,执行上面的命令,但再添加一个命令:

db=> ALTER USER readonlyuser SET search_path=customschema, public;
ALTER ROLE