AWS Redshift:如果用户不存在,我可以使用案例语句创建新用户吗?

Posted

技术标签:

【中文标题】AWS Redshift:如果用户不存在,我可以使用案例语句创建新用户吗?【英文标题】:AWS Redshift: Can I use a case statement to create a new user if the user doesn't already exist? 【发布时间】:2020-02-27 15:27:08 【问题描述】:

我正在尝试在 AWS 中自动创建用户。但是,如果我只是编写用户创建脚本,如果重新运行并且用户已经存在,它们将失败。

我在 AWS Redshift 工作。

我希望能够做类似的事情

CREATE USER IF NOT EXISTS usr_name
   password '<random_secure_password>'
   NOCREATEDB
   NOCREATEUSER
;

然而这似乎不可能。

然后我找到了 CASE 语句,但 CASE 语句似乎也不适用于我。

CASE WHEN
   SELECT count(*) FROM pg_user WHERE usename = 'usr_name' = 0
   THEN
   CREATE USER usr_name
      password '<random_secure_password>'
      NOCREATEDB
      NOCREATEUSER
END

这行得通吗? (不是超级用户,所以无法自己测试)

如果没有,有什么想法吗?有什么帮助,在此先感谢。

【问题讨论】:

【参考方案1】:

如果您使用 psql,您可以使用 \gexec 元命令:

 \t on
 BEGIN;

 SELECT CASE WHEN (SELECT count(*) FROM pg_user WHERE usename = 'nonesuch') = 0
        THEN 'CREATE USER nonesuch PASSWORD DISABLE'
        END
 \gexec

 SELECT CASE WHEN (SELECT count(*) FROM pg_user WHERE usename = 'nonesuch') = 0
        THEN 'CREATE USER nonesuch PASSWORD DISABLE'
        ELSE 'SELECT \'user already exists, doing nothing\''
        END
 \gexec

 ROLLBACK;

结果:

BEGIN
CREATE USER
user already exists, doing nothing
ROLLBACK

https://www.postgresql.org/docs/9.6/app-psql.html(请注意,您不能像示例中那样使用format(),因为它没有在 Redshift 中实现)

【讨论】:

【参考方案2】:

据我所知,在 Redshift 中(目前)没有机制可以做到这一点,并且向更多云模型的过渡让我合作过的许多公司都感到不安。许多本地数据库都有望成为他们自己的操作世界,其中所有事情都必须通过 SQL 在数据库内完成,无论这些是否是数据操作。我称之为“通用数据库”模型。 Redshift 是更大的 AWS 云解决方案生态系统的一部分,其中许多管理/管理/灵活性操作最好在云层完成,而不是在数据库中。 “数据的数据库”模型。

您没有解释为什么需要测试用户是否存在并在用户不存在时创建它们,或者为什么要在 SQL 中完成此决定。我确实希望一定程度的“这就是我们过去的做法”正在发挥作用。您想要做的可以是 Lambda(带或不带)Step Function,可能可以在您的 ETL 解决方案中完成,甚至可以编写为 bash 脚本。您要做的事情实际上很简单,我建议您考虑将其作为解决方案级别架构的一部分 - 而不是作为点数据库操作。

现在您可能会问:“如果这很容易,为什么 Redshift 不能做到?”公平点,我被问过很多次。一个答案是 Redshift 是一个基于云的大数据分析仓库,因此它旨在在这种情况下运行。另一个答案是,如果有足够多的大客户表现出需要并要求将添加的功能(AWS 确实会做出反应以满足一般需求)。请记住,有数以千计的地方可以添加新的 SQL 命令选项,但不会将所有这些选项都添加到 Redshift 中 - 事实上,几乎每个数据库都会频繁地提出这种类型的增强请求。

我的建议是退后一步,看看您的用户和用户权限管理应该如何适用于您的解决方案,而不仅仅是适用于数据库。然后转移到在解决方案的适当层(无论您决定是什么)管理这些权限的架构。 Redshift 用户可以与 IAM 集成,IAM 可用于控制对其他系统和其他数据库的访问。我知道这种更改需要工作和时间才能完成(并且可能会影响组织角色),所以在那之前我会查看您现有的数据库控制系统(ETL、真空/分析启动器、指标收集器等),看看哪些可以满足您的近期需求。

【讨论】:

【参考方案3】:

使用用户名作为参数创建一个存储过程并在其中进行检查。您可以在部署步骤中调用此存储过程。只有数据库创建不能在块内完成。用户可以在存储过程中创建。


    CREATE OR REPLACE PROCEDURE sp_create_user(i_username varchar) 
    AS $$
    DECLARE 
        t_user_count       BIGINT;
    BEGIN 
        SELECT count(1)
        INTO t_user_count
        FROM pg_user WHERE LOWER(usename) = 'username';
        IF t_user_count>0 THEN
            RAISE INFO 'User already exists';
        ELSE
            CREATE USER username WITH PASSWORD 'password' NOCREATEDB NOCREATEUSER;
        END IF;
    EXCEPTION 
        WHEN OTHERS THEN 
            RAISE EXCEPTION '[Error while creating user: username] Exception: %', SQLERRM;
    END;
    $$
    LANGUAGE plpgsql;

【讨论】:

以上是关于AWS Redshift:如果用户不存在,我可以使用案例语句创建新用户吗?的主要内容,如果未能解决你的问题,请参考以下文章

如果 S3 前缀不存在,Redshift COPY 命令会引发错误

在 aws redshift 中删除用户

优化 AWS RedShift 查询

在不使用 aws 凭据的情况下连接 Redshift 和 Python(在 emr 上运行)

如何将 AWS Redshift 用户活动日志解析为对象?

Python SQLalchemy 包...如果数据库在 AWS 上,它肯定是 Redshift 吗?