在 Postgres 中删除 USER(具有特权)IF EXIST

Emi*_*l G 7 postgresql automated-tests

我需要有条件地在 Postgres 中删除一个用户(如果它不存在)。DROP USER IF EXIST 很好,但根据文档,我还需要先删除权限,但是 DROP OWNED 或 REVOKE 似乎有条件 IF EXIST 子句。如何有条件地删除用户的权限?

我的数据库是 Postgres v9.6

背景:

我正在尝试为 Postgres 创建一组设置/拆卸脚本,这些脚本将为一系列函数创建一个测试区域。安装脚本应该:

  • 创建一个用户(如果它不存在)
  • 创建包含一些表的架构(如果尚不存在)

和拆解将:

  • 删除用户(如果存在)
  • 删除架构(如果存在)

问题是测试套件可能会被中断并使数据库/测试区域处于损坏状态(例如,如果从未执行过拆卸),因此我必须在我的脚本中考虑到这一点。

根据 Postgres 的文档:

如果角色在集群的任何数据库中仍然被引用,则无法删除该角色;如果是这样,将引发错误。在删除角色之前,您必须删除它拥有的所有对象(或重新分配其所有权)

我的用户拥有一项特权,即 CONNECT 到我的测试模式所在的测试数据库。这是因为我打算使用测试用户登录并执行测试。

但是因为似乎没有关于 DROP OWNED BY 或 REVOKE 的任何条件子句,我看不出怎么做?

dai*_*ain 7

只是为了让其他人不必使用 @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$$;
Run Code Online (Sandbox Code Playgroud)


Emi*_*l G 4

也许我缺少一些更简单的解决方案,但从问题Detect role in Postgresqldynamic来看,似乎一种解决方案是使用匿名代码块:

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

  • 谢谢,这使我得到了此处描述的较短版本/sf/answers/790997791/,它不需要“count”变量 (2认同)