加入收藏 | 设为首页 | 会员中心 | 我要投稿 银川站长网 (https://www.0951zz.com/)- 云通信、基础存储、云上网络、机器学习、视觉智能!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

用Superset如何做SQL动态查询的

发布时间:2023-05-13 11:01:13 所属栏目:MsSql教程 来源:
导读:这篇文章给大家分享的是用Superset怎样做SQL动态查询的。小编觉得挺实用的,因此分享给大家做个参考,文中的介绍得很详细,而要易于理解和学习,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。使用自定义参

这篇文章给大家分享的是用Superset怎样做SQL动态查询的。小编觉得挺实用的,因此分享给大家做个参考,文中的介绍得很详细,而要易于理解和学习,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。

使用自定义参数方式实现 superset 实现SQL动态查询。

1、启用参数:config.py 设置"ENABLE_TEMPLATE_PROCESSING": True

2、当前superset v1.2版本支持的参数包括:

{{ current_username() }}   当前登录用户名

{{ current_username(add_to_cache_keys=False) }}  不从缓存中获取登录用户名,默认从缓存获取

{{ current_user_id()}}   当前登录用户ID

{{ current_user_id(add_to_cache_keys=False) }}  不从缓存中获取登录用户ID,默认从缓存获取

{{ url_param('custom_variable') }} url 参数,比如127.0.0.1:8001\dashboard?abc=123,参数就是{{ url_param('abc') }} 结果就是123

{{ cache_key_wrapper() }}  还没有弄明白啥用

{{ filter_values("字段名") }} 获取dashboard filter_box组件对某个字段的筛选结果

{{ from_dttm }} 获取dashboard filter_box组件日期筛选的开始时间

{{ to_dttm }}  获取dashboard filter_box组件日期筛选的结束时间

{{ get_filters() }} 暂时没有弄明白

除此之外,还可以自定义参数,自定义参数方法:

修改superset/jinja_context.py文件,修改三个地方:

regex = re.compile(

r"\{\{.*("

r"current_user_id\(.*\)|"

r"current_username\(.*\)|"

r"current_userroles\(.*\)|"

r"isadmin\(.*\)|"

r"cache_key_wrapper\(.*\)|"

r"url_param\(.*\)"

r").*\}\}"

)

注意此处的 current_userroles 和 isadmin 是我自定义的,源文件没有

def current_user_id(self, add_to_cache_keys: bool = True) -> Optional[int]:

"""

Return the user ID of the user who is currently logged in.

:param add_to_cache_keys: Whether the value should be included in the cache key

:returns: The user ID

"""

if hasattr(g, "user") and g.user:

if add_to_cache_keys:

self.cache_key_wrapper(g.user.get_id())

return g.user.get_id()

return None

def current_username(self, add_to_cache_keys: bool = True) -> Optional[str]:

"""

Return the username of the user who is currently logged in.

:param add_to_cache_keys: Whether the value should be included in the cache key

:returns: The username

"""

if g.user and hasattr(g.user, "username"):

if add_to_cache_keys:

self.cache_key_wrapper(g.user.username)

return g.user.username

return None

def current_userroles(self, add_to_cache_keys: bool = True) -> Optional[str]:

"""

Return the roles of the user who is currently logged in.

:param add_to_cache_keys: Whether the value should be included in the cache key

:returns: The userroles

"""

if g.user and hasattr(g.user, "roles"):

if add_to_cache_keys:

user_roles = "/".join([role.name.lower() for role in list(g.user.roles)])

self.cache_key_wrapper(user_roles)

print(user_roles)

return user_roles

"""admin in user_roles"""

return None

def isadmin(self, add_to_cache_keys: bool = True) -> Optional[str]:

"""

Return the roles of the user who is currently logged in.

:param add_to_cache_keys: Whether the value should be included in the cache key

:returns: The userroles

"""

if g.user and hasattr(g.user, "roles"):

if add_to_cache_keys:

user_roles = [role.name.lower() for role in list(g.user.roles)]

return "admin" in user_roles

return None

仿照系统自带的 current_username 编造自己的函数,我写了current_userroles 和 isadmin

class JinjaTemplateProcessor(BaseTemplateProcessor):

def set_context(self, **kwargs: Any) -> None:

super().set_context(**kwargs)

extra_cache = ExtraCache(self._extra_cache_keys)

self._context.update(

{

"url_param": partial(safe_proxy, extra_cache.url_param),

"current_user_id": partial(safe_proxy, extra_cache.current_user_id),

"current_username": partial(safe_proxy, extra_cache.current_username),

"current_userroles": partial(safe_proxy, extra_cache.current_userroles),

"isadmin": partial(safe_proxy, extra_cache.isadmin),

"cache_key_wrapper": partial(safe_proxy, extra_cache.cache_key_wrapper),

"filter_values": partial(safe_proxy, filter_values),

}

)

仿照系统自带的 current_username 编造自己的函数,我写了current_userroles 和 isadmin。

就是这3个地方,但是注意,自己在第二步早的函数,返回值必须是:

ALLOWED_TYPES = (

NONE_TYPE,

"bool",

"str",

"unicode",

"int",

"long",

"float",

"list",

"dict",

"tuple",

"set",

)

否则会提示错误,或者自己修改这个types,我是转换,比如上面那个g.user.roles 返回的结果就不是上面类型,导致我一直不成功,最后修改了下,才可以。

3、判断是否自定义成功:

在superset sql lab中执行如下代码,如果能被解析,就说明成功。

4、应用案例:

 在dataset里面,动态访问数据源,数据源添加where语句:select * from sales where salesname =' {{current_username()}}'

dashboard里面,通过获取筛选器的结果,然后获取其他表应当显示的数据范围:

select DATE,risktype,sum(num) as num from

(SELECT date , customerid,product,risktype ,count(*) as num

from v_superset_forecast_risk group by date , customerid,product,risktype ) a

join

(select distinct customer_code,product from v_superset_access

where name='{{ current_username() }}' )access

on a.customerid=access.customer_code

and a.product=access.product

and DATE_FORMAT(date,'%Y-%m')> DATE_FORMAT(date_sub(STR_TO_DATE(concat( {{ "'" + "', '".join(filter_values('yearmonthend')) + "'" }},'-01'), '%Y-%m-%d'), interval 12 month),'%Y-%m')

and DATE_FORMAT(date,'%Y-%m')<={{ "'" + "', '".join(filter_values('yearmonthend')) + "'" }}

group by DATE,risktype

因为sql里面可以使用jinja 表达式,比如判断筛选当前没有筛选的时候,获取什么数据。

 注意{%  %} 内部使用参数的时候,不需要加{{}},否则报错,通过筛选器实现模糊查询。

 5、官方参考文档:

https://superset.apache.org/docs/installation/sql-templating

官方没有那么详细,但是里面有一些我这里可能也没有消化吸收掉,可以参考看下。

总之,通过上面的自定义参数方法,和jinja表达式在sql中的应用,可以实现动态查询,解决一些无法通过页面直接交互查询结果显示的内容。

“用Superset怎样做SQL动态查询的”的内容就介绍到这里了,感谢大家的阅读。

(编辑:银川站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章