删除具有特权的角色
Drop a role with privileges
这看起来像是一个非常基本的需求,但我没有找到任何快速和合适的答案。我在 Postgres 中有一个角色,它对各种数据库中的许多其他表具有特权。
我需要放弃这个角色。我有一个 postgres 实例,然后在它上面有许多数据库。
SELECT DISTINCT 'REVOKE ALL ON TABLE ' || table_schema || '.' || table_name || ' FROM ' || r.param_role_name || ';'
FROM information_schema.table_privileges CROSS JOIN (SELECT 'some_role_name'::text AS param_role_name) r
WHERE grantee ~* r.param_role_name;
我可以像上面那样做,通过访问每个数据库并找到所有撤销语句然后删除角色。有什么办法可以在一个地方找到所有数据库的所有撤销语句。
或者像我可以改变这个角色拥有的东西,我可以用一条语句改变所有特权吗?
Edit1:由于大多数回复的目标是重新分配拥有者和删除拥有者,我想说得更具体一些。
我可以在每个数据库上执行以下命令,并在删除所有依赖项后删除角色。
REASSIGN OWNED BY some_role_name TO postgres;
DROP OWNED BY some_role_name;
但是有很多数据库,所以我正在寻找可以强制刷新所有权限并删除此角色的东西。
I need to drop this role.
运行 在同一集群的每个数据库中,该角色可能拥有任何东西或具有任何授予的特权:
REASSIGN OWNED BY some_role_name TO postgres;
DROP OWNED BY some_role_name;
postgres
作为默认的超级用户,您可以选择任何其他用户。它将拥有当前由旧角色拥有的对象。 REASSIGN OWNED
, there are no objects left that would be owned by the same user. It may seem unintuitive to run DROP OWNED
. The wording of the command is misleading, since it also revokes all privileges and default privileges for the role in the same database. The manual:
之后立即
DROP OWNED
drops all the objects within the current database that are owned by one of the specified roles. Any privileges granted to the given roles on objects in the current database and on shared objects (databases, tablespaces) will also be revoked.
大胆强调我的。
您仍然必须在 每个数据库 中执行它,角色拥有任何东西或具有任何授予的特权。手册:
Because REASSIGN OWNED
does not affect objects within other databases, it is usually necessary to execute this command in each database that contains objects owned by a role that is to be removed.
最后,运行(一次):
DROP role some_role_name;
角色存储在集群范围的系统目录中,而对象的所有权和特权存储在数据库本地系统目录中。
详细解释在这个相关回答中:
有一个相关的 page in the manual with instructions.
全自动化
没有一个命令可以完成这一切。但是你可以让Postgres为你生成一个完整的psql脚本。
角色的依赖关系存储在系统目录中pg_shdepend
:
This information allows PostgreSQL to ensure that those objects are unreferenced before attempting to delete them.
因为我们(可能)需要连接到不同的数据库,所以我们需要 psql 元命令 (\c my_database
) 和 SQL DDL 命令的组合,如上所示。在您的数据库集群中的某处创建此函数一次:
CREATE OR REPLACE FUNCTION f_generate_ddl_to_remove_role(dead_role_walking regrole)
RETURNS text
LANGUAGE sql AS
$func$
SELECT concat_ws(
E'\n'
,(SELECT string_agg(format(E'\c %I\nREASSIGN OWNED BY %2$s TO postgres; DROP OWNED BY %2$s;'
, d.datname, dead_role_walking)
, E'\n')
FROM (
SELECT DISTINCT dbid
FROM pg_shdepend
WHERE refobjid = dead_role_walking
) s
JOIN pg_database d ON d.oid = s.dbid)
, format(E'DROP role %s;\n', dead_role_walking)
)
$func$;
致电:
SELECT f_generate_ddl_to_remove_role('some_role_name');
生成如下字符串:
\c my_db1
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
\c my_db2
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
DROP role some_role_name;
或者,如果该角色不拥有任何东西并且没有特权,只需:
DROP role some_role_name;
如果您提供一个不存在的角色名称,您会收到错误消息。
将字符串(不包含单引号)复制到使用 postgres
等超级用户打开的 psql 会话。或者用它连接一个 bash 脚本。全部完成。
有几个相关的答案,对动态有更多的解释 SQL:
在任何数据库中存在相关对象之前,您不能删除角色。
您必须将此用户 (some_role_name) 拥有的对象重新分配给另一个用户。
对所有数据库中的所有对象完成后,您就可以删除该用户。
REASSIGN OWNED BY some_role_name TO some_other_role_name;
如果不需要依赖对象,您也可以继续使用 DROP OWNED BY,删除所有属于 some_role_name 的对象。
DROP OWNED BY some_role_name;
这看起来像是一个非常基本的需求,但我没有找到任何快速和合适的答案。我在 Postgres 中有一个角色,它对各种数据库中的许多其他表具有特权。
我需要放弃这个角色。我有一个 postgres 实例,然后在它上面有许多数据库。
SELECT DISTINCT 'REVOKE ALL ON TABLE ' || table_schema || '.' || table_name || ' FROM ' || r.param_role_name || ';'
FROM information_schema.table_privileges CROSS JOIN (SELECT 'some_role_name'::text AS param_role_name) r
WHERE grantee ~* r.param_role_name;
我可以像上面那样做,通过访问每个数据库并找到所有撤销语句然后删除角色。有什么办法可以在一个地方找到所有数据库的所有撤销语句。
或者像我可以改变这个角色拥有的东西,我可以用一条语句改变所有特权吗?
Edit1:由于大多数回复的目标是重新分配拥有者和删除拥有者,我想说得更具体一些。 我可以在每个数据库上执行以下命令,并在删除所有依赖项后删除角色。
REASSIGN OWNED BY some_role_name TO postgres;
DROP OWNED BY some_role_name;
但是有很多数据库,所以我正在寻找可以强制刷新所有权限并删除此角色的东西。
I need to drop this role.
运行 在同一集群的每个数据库中,该角色可能拥有任何东西或具有任何授予的特权:
REASSIGN OWNED BY some_role_name TO postgres;
DROP OWNED BY some_role_name;
postgres
作为默认的超级用户,您可以选择任何其他用户。它将拥有当前由旧角色拥有的对象。 REASSIGN OWNED
, there are no objects left that would be owned by the same user. It may seem unintuitive to run DROP OWNED
. The wording of the command is misleading, since it also revokes all privileges and default privileges for the role in the same database. The manual:
DROP OWNED
drops all the objects within the current database that are owned by one of the specified roles. Any privileges granted to the given roles on objects in the current database and on shared objects (databases, tablespaces) will also be revoked.
大胆强调我的。
您仍然必须在 每个数据库 中执行它,角色拥有任何东西或具有任何授予的特权。手册:
Because
REASSIGN OWNED
does not affect objects within other databases, it is usually necessary to execute this command in each database that contains objects owned by a role that is to be removed.
最后,运行(一次):
DROP role some_role_name;
角色存储在集群范围的系统目录中,而对象的所有权和特权存储在数据库本地系统目录中。
详细解释在这个相关回答中:
有一个相关的 page in the manual with instructions.
全自动化
没有一个命令可以完成这一切。但是你可以让Postgres为你生成一个完整的psql脚本。
角色的依赖关系存储在系统目录中pg_shdepend
:
This information allows PostgreSQL to ensure that those objects are unreferenced before attempting to delete them.
因为我们(可能)需要连接到不同的数据库,所以我们需要 psql 元命令 (\c my_database
) 和 SQL DDL 命令的组合,如上所示。在您的数据库集群中的某处创建此函数一次:
CREATE OR REPLACE FUNCTION f_generate_ddl_to_remove_role(dead_role_walking regrole)
RETURNS text
LANGUAGE sql AS
$func$
SELECT concat_ws(
E'\n'
,(SELECT string_agg(format(E'\c %I\nREASSIGN OWNED BY %2$s TO postgres; DROP OWNED BY %2$s;'
, d.datname, dead_role_walking)
, E'\n')
FROM (
SELECT DISTINCT dbid
FROM pg_shdepend
WHERE refobjid = dead_role_walking
) s
JOIN pg_database d ON d.oid = s.dbid)
, format(E'DROP role %s;\n', dead_role_walking)
)
$func$;
致电:
SELECT f_generate_ddl_to_remove_role('some_role_name');
生成如下字符串:
\c my_db1
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
\c my_db2
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
DROP role some_role_name;
或者,如果该角色不拥有任何东西并且没有特权,只需:
DROP role some_role_name;
如果您提供一个不存在的角色名称,您会收到错误消息。
将字符串(不包含单引号)复制到使用 postgres
等超级用户打开的 psql 会话。或者用它连接一个 bash 脚本。全部完成。
有几个相关的答案,对动态有更多的解释 SQL:
在任何数据库中存在相关对象之前,您不能删除角色。
您必须将此用户 (some_role_name) 拥有的对象重新分配给另一个用户。 对所有数据库中的所有对象完成后,您就可以删除该用户。
REASSIGN OWNED BY some_role_name TO some_other_role_name;
如果不需要依赖对象,您也可以继续使用 DROP OWNED BY,删除所有属于 some_role_name 的对象。
DROP OWNED BY some_role_name;