如何在Python中递归遍历Snowflake角色授予层次结构?

问题描述 投票:0回答:2

有人编写过 Python 代码来遍历 Snowflake 角色层次结构吗?

一个角色可以被授予一个角色,该角色可以被授予一个角色。

可以嵌套角色。

在Python中,我想从一个特定的角色开始

  1. 查询该角色的所有授权是roles
  2. 将每一个都存储在一个唯一的列表中
  3. 对于每个角色执行一条 SQL 语句,该语句将查询授予该角色的所有角色

并向下遍历层次结构,不遗漏任何一个角色,也不遍历已经查询过的或待查询列表中的角色

使用 Python 递归地爬取这棵树会很有帮助。

此时,给定一个角色,我无法执行一条 SQL 语句来为我提供授予给定角色的所有第一级子角色。

无法选择 ROLE 类型的字段并获得授权。

如有任何帮助,我们将不胜感激。

一旦完成,我会将所有贡献和最终代码发布到 github 帐户。

谢谢你,

我希望最终得到一个雪花角色列表,列表中没有重复项。

python sql recursion snowflake-cloud-data-platform directed-acyclic-graphs
2个回答
3
投票

您说“此时,给定一个角色,我无法执行一条 SQL 语句来为我提供授予给定角色的所有第一级子角色。” - 这不是真的。

你可以这样做:

SHOW GRANTS TO ROLE THE_ROLE;  -- replace THE_ROLE with your role name
SELECT distinct "name" FROM table(result_scan(last_query_id())) where "privilege" = 'USAGE' and "granted_on" = 'ROLE';

嗯,它们实际上是两个查询。

但也可以用一个来实现:

select name
from snowflake.account_usage.grants_to_roles
where grantee_name = 'THE_ROLE' -- replace THE_ROLE with your role name
and granted_on = 'ROLE'
and privilege = 'USAGE'
and deleted_on is null;

您还可以通过递归查询获取整个层次结构,如下所示:

with cte as (
    select * 
    from snowflake.account_usage.grants_to_roles
    where grantee_name = 'THE_ROLE'  -- replace THE_ROLE with your role name
        and granted_on = 'ROLE'
        and privilege = 'USAGE'
        and deleted_on is null

    UNION ALL 

    select gtr.*
    from snowflake.account_usage.grants_to_roles gtr 
    join cte on gtr.grantee_name = cte.name
    where gtr.granted_on = 'ROLE'
    and gtr.privilege = 'USAGE'
    and gtr.deleted_on is null
)
select * from cte;

查询 SNOWFLAKE.ACCOUNT_USAGE 视图是烦人的雪,所以我建议在数据库中创建一个副本并使用它来播放和测试。


0
投票

@Limonka 提供的递归方法的答案会很好,但在用户无权访问 SNOWFLAKE.ACCOUNT_USAGE 视图的情况下,还有另一个选项可以获取直接授予用户的所有角色以及层次结构中较低的所有角色这些角色。

CURRENT_AVAILABLE_ROLES()

返回一个字符串 (VARCHAR),其中列出了授予的所有帐户级角色 给当前用户。

返回的字符串包含 JSON 编码的所有角色列表 用户可以在用户会话中激活

了解更多详细信息 - https://docs.snowflake.com/en/sql-reference/functions/current_available_roles

© www.soinside.com 2019 - 2024. All rights reserved.