我的数据库中有一些与不同供应商相关的信息,我希望允许每个注册供应商(代表人)查看仅包含与它们相关的数据的切片/仪表板。一种可能的解决方案是为每个供应商创建单独的视图以及为每个供应商创建单独的角色。但是,如果您有 100 多个供应商(就像我的情况),那感觉是个坏主意;它不是一个灵活或可扩展的解决方案。有没有办法为每个用户自动过滤给定的视图?例如,我们有一个“按产品划分的一般利润”条形图,用户 X 只能看到供应商 X 的产品
3 回答
您正在寻找的是多租户支持,目前在 Superset 中不支持开箱即用。
然而,有一个可能的解决方案的公开 PR:https ://github.com/apache/incubator-superset/pull/3729
一种选择可能是为您的用例重用和/或调整该代码。
另一种选择可能是查看JINJA_CONTEXT_ADDONS
[ https://github.com/apache/incubator-superset/blob/master/docs/installation.rst#sql-lab]并查看您是否能够将其他上下文传递给您的查询(例如您的 vendor_id)并使用该参数限制您的查询范围。
解决此问题的一种简单方法是使用预定义的 JINJA 参数。可以使用的两个参数是 '{{current_username() }}' 和 {{current_user_id() }}
首先,您需要确保您可以使用 JINJA 模板 - 在 superset_config.py 中添加以下内容
FEATURE_FLAGS = {
"ENABLE_TEMPLATE_PROCESSING": True,
}
重新开始
现在,如果您转到 SQL LAB 并键入以下内容 -
SELECT '{{ current_username() }}',{{ current_user_id() }};
你应该得到一个输出
?柱子? | ?列?__1 |
---|---|
PayalC | 5 |
现在您所要做的就是在所有查询中附加以下两个 sql 片段之一。
select ........ from ...... where ...... vendorid={{ current_user_id() }}
select ........ from ...... where ...... vendorname='{{ current_username() }}'
vendorid={{ current_user_id() }} 和/或 vendorname='{{ current_username() }}' 将限制用户仅查看她的数据。
您还可以通过创建一个将用户映射到供应商 ID 的表来使其更加灵活。该表可以添加到所有查询中,并且您可以将多个供应商映射到单个用户,甚至可以将所有供应商映射到单个用户以获得超级管理员。
Superset config 有以下两种配置(DB_CONNECTION_MUTATOR,SQL_QUERY_MUTATOR),可以在一定程度上允许多租户。
允许在运行时动态更改数据库连接 URL 和参数的可调用对象。这允许诸如模仿或任意逻辑之类的事情。例如,您可以连接不同的用户以使用不同的连接参数,或者将他们的电子邮件地址作为用户名传递。该函数接收连接 uri 对象、连接参数、用户名,并返回变异的 uri 和 params 对象。例子:
def DB_CONNECTION_MUTATOR(uri, params, username, security_manager, source):
user = security_manager.find_user(username=username)
if user and user.email:
uri.username = user.email
return uri, params
请注意,返回的 uri 和 params 直接传递给 sqlalchemycreate_engine(url, **params)
DB_CONNECTION_MUTATOR = None
拦截要执行的 SQL 并可以更改它的函数。用例可以围绕添加某种带有用户名和工作节点信息等信息的注释头
def SQL_QUERY_MUTATOR(sql, username, security_manager):
dttm = datetime.now().isoformat()
return f"-- [SQL LAB] {username} {dttm}\n{sql}"
SQL_QUERY_MUTATOR = None