如果 Postgres 中存在,则删除 USER(具有特权)
Posted
技术标签:
【中文标题】如果 Postgres 中存在,则删除 USER(具有特权)【英文标题】:Drop USER (with privileges) IF EXIST in Postgres 【发布时间】:2016-11-29 09:24:28 【问题描述】:我需要有条件地在 Postgres 中删除一个用户(如果它不存在)。 DROP USER IF EXIST 很好,但根据文档,我还需要先删除权限,但是 DROP OWNED 或 REVOKE 似乎有条件 IF EXIST 子句。如何有条件地删除我的用户的权限?
我的数据库是 Postgres v9.6
背景:
我正在尝试为 Postgres 创建一组设置/拆卸脚本,这些脚本将为一堆函数创建一个测试区域。安装脚本应该:
创建用户(如果尚不存在) 创建包含一些表的架构(如果尚不存在)拆解将:
删除用户(如果存在) 删除架构(如果存在)问题是测试套件可能会被中断并使数据库/测试区域处于损坏状态(例如,如果从未执行过拆卸),所以我必须在我的脚本中考虑这一点。
根据 Postgres 的文档:
如果角色仍然在集群的任何数据库中被引用,则无法删除该角色;如果是这样,将引发错误。在删除角色之前,您必须删除它拥有的所有对象(或重新分配其所有权)
我的用户有一个权限,即连接到我的测试架构所在的测试数据库。这是因为我打算使用测试用户登录并执行测试。
但是因为在 DROP OWNED BY 或 REVOKE 上似乎没有任何条件子句,我看不出如何做到这一点?
【问题讨论】:
【参考方案1】:也许我缺少一些更简单的解决方案,但从问题Detect role in Postgresql dynamically 看来,一种解决方案是使用匿名代码块:
-- Only revoke if user 'my_user exists'
DO $$DECLARE count int;
BEGIN
SELECT count(*) INTO count FROM pg_roles WHERE rolname = 'my_user';
IF count > 0 THEN
EXECUTE 'REVOKE CONNECT ON DATABASE "my-testdb" FROM my_user';
END IF;
END$$;
-- No privileges left, now it should be possible to drop
DROP USER IF EXISTS my_user;
【讨论】:
谢谢,这使我得到了此处描述的较短版本***.com/a/11299968/138256,它不需要“计数”变量【参考方案2】:只是为了让其他人不必考虑如何使用@codebox评论中的链接来简化语句:
DO
$$BEGIN
IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'my_user') THEN
EXECUTE 'REVOKE CONNECT ON DATABASE "postgres" FROM my_user';
END IF;
END$$;
【讨论】:
以上是关于如果 Postgres 中存在,则删除 USER(具有特权)的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data 错误:“HHH000389 不成功:如果存在则删除表”
Postgres 测试容器 - 如果存在级联,为啥要在删除表之前删除约束?
如何参数化 Postgres-custom-function 中的表和列,如果值存在则选择 PK,否则插入并返回 PK?