在Superset中,支持利用Jinja模板进行sql注入
如果是要启用这个功能,则需要在config.py中设置 Feature_flag中的ENABLE_TEMPLATE_PROCESSING 为 True
之后就可以启动Jinja模板了
其可以通过对SQL中的子查询进行查询注入
常用的变量有
比如常见的
Select * from tbl where
Dttm_col > ‘{{from_dttm}}’ AND Dttm_col < ‘{{to_dttm}}’
除了最常见的time range,还有就是我们常用的filter
对于filter,常见的可以进行筛选值
SELECT action, count(*) as times
FROM logs
WHERE
action in {{ filter_values(‘action_type’)|where_in }}
GROUP BY action
筛选器将值列表转换为适合表达式的字符串。where_infilter_values(‘action_type’)IN
或者
SELECT action, count(*) as times
FROM logs
WHERE
action in ({{ “‘” + “‘,'”.join(filter_values(‘action_type’)) + “‘” }})
GROUP BY action
或者进行特定列的筛选
可以利用其提供的函数 get_filters()
就比如如下的函数
WITH RECURSIVE
superiors(employee_id, manager_id, full_name, level, lineage) AS ( SELECT employee_id, manager_id, full_name, 1 as level, employee_id as lineage FROM employees WHERE 1=1 {%- for filter in get_filters(‘full_name’, remove_filter=True) -%} {%- if filter.get(‘op’) == ‘IN’ -%} AND full_name IN {{ filter.get(‘val’)|where_in }} {%- endif -%} {%- if filter.get(‘op’) == ‘LIKE’ -%} AND full_name LIKE {{ “‘” + filter.get(‘val’) + “‘” }} {%- endif -%} {%- endfor -%} UNION ALL SELECT e.employee_id, e.manager_id, e.full_name, s.level + 1 as level, s.lineage FROM employees e, superiors s WHERE s.manager_id = e.employee_id ) SELECT employee_id, manager_id, full_name, level, lineage FROM superiors ORDER BY lineage, level |
上面是一个遍历所有的filter,并进行动态拼接的sql
解下来我们看一个实例
首先我们在sql lab中创建一个dataset
select * from public.ab_user
where 1=1 |
然后我们在对这个dataset进行修改,修改其sql为
select * from public.ab_user
where 1=1 {%- for filter in get_filters(‘username’, remove_filter=True) -%} {%- if filter.get(‘op’) == ‘IN’ -%} AND username IN {{ filter.get(‘val’)|where_in }} {%- endif -%} {%- if filter.get(‘op’) == ‘LIKE’ -%} AND username LIKE {{ “‘” + filter.get(‘val’) + “‘” }} {%- endif -%} {%- endfor -%} |
之后我们利用其制作chart
并且将chart增加到dashboard中
在其中增加一个filter,关于username这个字段的过滤
从而进行使用
这样过滤后,可以通过view query,查看这个filter已经应用到子查询中了。