mirror of
https://github.com/apache/superset.git
synced 2026-04-07 10:31:50 +00:00
feat: add support for filters in sqlLab (#14765)
This commit is contained in:
@@ -1256,6 +1256,37 @@ in this dictionary are made available for users to use in their SQL.
|
|||||||
'my_crazy_macro': lambda x: x*2,
|
'my_crazy_macro': lambda x: x*2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Default values for jinja templates can be specified via ``Parameters`` menu in the SQL Lab user interface.
|
||||||
|
In the UI you can assign a set of parameters as JSON
|
||||||
|
|
||||||
|
.. code-block:: JSON
|
||||||
|
{
|
||||||
|
"my_table": "foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
The parameters become available in your SQL (example:SELECT * FROM {{ my_table }} ) by using Jinja templating syntax.
|
||||||
|
SQL Lab template parameters are stored with the dataset as TEMPLATE PARAMETERS.
|
||||||
|
|
||||||
|
There is a special ``_filters`` parameter which can be used to test filters used in the jinja template.
|
||||||
|
|
||||||
|
.. code-block:: JSON
|
||||||
|
{
|
||||||
|
"_filters": {
|
||||||
|
"col": "action_type",
|
||||||
|
"op": "IN",
|
||||||
|
"val": ["sell", "buy"]
|
||||||
|
}
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
SELECT action, count(*) as times
|
||||||
|
FROM logs
|
||||||
|
WHERE
|
||||||
|
action in ({{ "'" + "','".join(filter_values('action_type')) + "'" }})
|
||||||
|
GROUP BY action
|
||||||
|
|
||||||
|
Note ``_filters`` is not stored with the dataset. It's only used within the SQL Lab UI.
|
||||||
|
|
||||||
|
|
||||||
Besides default Jinja templating, SQL lab also supports self-defined template
|
Besides default Jinja templating, SQL lab also supports self-defined template
|
||||||
processor by setting the ``CUSTOM_TEMPLATE_PROCESSORS`` in your superset configuration.
|
processor by setting the ``CUSTOM_TEMPLATE_PROCESSORS`` in your superset configuration.
|
||||||
The values in this dictionary overwrite the default Jinja template processors of the
|
The values in this dictionary overwrite the default Jinja template processors of the
|
||||||
|
|||||||
@@ -271,9 +271,22 @@ export default class ResultSet extends React.PureComponent<
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { schema, sql, dbId, templateParams } = this.props.query;
|
const { schema, sql, dbId } = this.props.query;
|
||||||
|
let { templateParams } = this.props.query;
|
||||||
const selectedColumns = this.props.query?.results?.selected_columns || [];
|
const selectedColumns = this.props.query?.results?.selected_columns || [];
|
||||||
|
|
||||||
|
// The filters param is only used to test jinja templates.
|
||||||
|
// Remove the special filters entry from the templateParams
|
||||||
|
// before saving the dataset.
|
||||||
|
if (templateParams) {
|
||||||
|
const p = JSON.parse(templateParams);
|
||||||
|
if (p.filters) {
|
||||||
|
/* eslint-disable-next-line no-underscore-dangle */
|
||||||
|
delete p._filters;
|
||||||
|
templateParams = JSON.stringify(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.props.actions
|
this.props.actions
|
||||||
.createDatasource({
|
.createDatasource({
|
||||||
schema,
|
schema,
|
||||||
|
|||||||
@@ -127,13 +127,16 @@ def loads_request_json(request_json_data: str) -> Dict[Any, Any]:
|
|||||||
def get_form_data( # pylint: disable=too-many-locals
|
def get_form_data( # pylint: disable=too-many-locals
|
||||||
slice_id: Optional[int] = None, use_slice_data: bool = False
|
slice_id: Optional[int] = None, use_slice_data: bool = False
|
||||||
) -> Tuple[Dict[str, Any], Optional[Slice]]:
|
) -> Tuple[Dict[str, Any], Optional[Slice]]:
|
||||||
form_data = {}
|
form_data: Dict[str, Any] = {}
|
||||||
# chart data API requests are JSON
|
# chart data API requests are JSON
|
||||||
request_json_data = (
|
request_json_data = (
|
||||||
request.json["queries"][0]
|
request.json["queries"][0]
|
||||||
if request.is_json and "queries" in request.json
|
if request.is_json and "queries" in request.json
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_sqllab_custom_filters(form_data)
|
||||||
|
|
||||||
request_form_data = request.form.get("form_data")
|
request_form_data = request.form.get("form_data")
|
||||||
request_args_data = request.args.get("form_data")
|
request_args_data = request.args.get("form_data")
|
||||||
if request_json_data:
|
if request_json_data:
|
||||||
@@ -196,6 +199,26 @@ def get_form_data( # pylint: disable=too-many-locals
|
|||||||
return form_data, slc
|
return form_data, slc
|
||||||
|
|
||||||
|
|
||||||
|
def add_sqllab_custom_filters(form_data: Dict[Any, Any]) -> Any:
|
||||||
|
"""
|
||||||
|
SQLLab can include a "filters" attribute in the templateParams.
|
||||||
|
The filters attribute is a list of filters to include in the
|
||||||
|
request. Useful for testing templates in SQLLab.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
data = json.loads(request.data)
|
||||||
|
if isinstance(data, dict):
|
||||||
|
params_str = data.get("templateParams")
|
||||||
|
if isinstance(params_str, str):
|
||||||
|
params = json.loads(params_str)
|
||||||
|
if isinstance(params, dict):
|
||||||
|
filters = params.get("filters")
|
||||||
|
if filters:
|
||||||
|
form_data.update({"filters": filters})
|
||||||
|
except (TypeError, json.JSONDecodeError):
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
|
||||||
def get_datasource_info(
|
def get_datasource_info(
|
||||||
datasource_id: Optional[int], datasource_type: Optional[str], form_data: FormData
|
datasource_id: Optional[int], datasource_type: Optional[str], form_data: FormData
|
||||||
) -> Tuple[int, Optional[str]]:
|
) -> Tuple[int, Optional[str]]:
|
||||||
|
|||||||
Reference in New Issue
Block a user