2017-10-12 99 views
1

我正在写一个将在暂存数据库和生产数据库上运行的Redshift迁移。我希望这种迁移能够授予用户访问权限,并且用户的名称取决于正在迁移的数据库。GRANT中的Redshift子查询

例如,如果当前DB是“staging_db”,我希望迁移将权限授予“staging_user”,如果当前DB是“prod_db”,则授予“prod_user”权限。

一个幼稚的做法是这样的:

GRANT SELECT 
ON TABLE my_table 
TO (SELECT CASE current_database() 
      WHEN 'staging_db' THEN 'staging_user' 
      WHEN 'prod_db' THEN 'db_user' 
      END); 

虽然,这个错误告诉我SELECT子查询未在GRANT语句允许:

ERROR: syntax error at or near "(" 
LINE 3: TO (SELECT CASE current_database() 

什么是这样做的首选方式在Redshift中?

编辑:我正在Clojure中运行Migratus的迁移,如果它可以有任何帮助的话。

回答

0

显然,Redshift没有处理语句中的子查询的机制。由于Redshift是PostgreSQL 8.0.2的一个分支,它在后来的Pos​​tgreSQL版本中都没有DO blocks功能。

更好的方法是为分段和生产环境设置完全独立的集群,而不是单独的数据库和用户。这将消除在SQL迁移语句中具有“如果逻辑”的需要,并且将避免在不同环境中共享相同群集的其他缺点。

有关如何降低分段/测试环境成本的有用提示,请参阅this后。

0

使用组(CREATE GROUP),以便您可以将权限分配给组。

然后你唯一的问题是需要的ALTER GROUP,可以做前面。因此迁移脚本可以被硬编码:

GRANT SELECT ON TABLE my_table TO MyGroup; 

更新,评论

PROD上后(反向分期)

ALTER GROUP MyGroup的ADD USER DB_USER; ALTER GROUP MyGroup DROP USER staging_user;

不要忘了GRANT USAGE ON SCHEMA

+0

感谢您的快速回答。将这两个用户放在同一组中,不幸的是,一旦迁移将在生产环境中运行,将授予对“prod_db”的“staging_user”访问权 – GeorgCantor

+0

@GeorgCantor仅授予基于环境的正确用户成员身份。也就是说,该组和成员可以在客户端单独或更动态地完成。 – gbn

+0

这不会导致同样的问题吗?我需要根据当前的数据库动态授予会员资格,这是我无法做到的。 – GeorgCantor

0

随着migratus可以运行EDN迁移从Clojure的具有完全可编程查询。

你应该能够在那里实现该子查询的逻辑!