[sqllab] Add CUSTOM_TEMPLATE_PROCESSOR config (#9376)

Co-authored-by: Dandan Shi <dshi@dropbox.com>
This commit is contained in:
dandanhub
2020-04-07 13:00:42 -07:00
committed by GitHub
parent a52b9ee8ff
commit 72f051f3ce
9 changed files with 258 additions and 2 deletions

View File

@@ -1087,6 +1087,59 @@ in this dictionary are made available for users to use in their SQL.
'my_crazy_macro': lambda x: x*2,
}
Besides default Jinja templating, SQL lab also supports self-defined template
processor by setting the ``CUSTOM_TEMPLATE_PROCESSORS`` in your superset configuration.
The values in this dictionary overwrite the default Jinja template processors of the
specified database engine.
The example below configures a custom presto template processor which implements
its own logic of processing macro template with regex parsing. It uses ``$`` style
macro instead of ``{{ }}`` style in Jinja templating. By configuring it with
``CUSTOM_TEMPLATE_PROCESSORS``, sql template on presto database is processed
by the custom one rather than the default one.
.. code-block:: python
def DATE(
ts: datetime, day_offset: SupportsInt = 0, hour_offset: SupportsInt = 0
) -> str:
"""Current day as a string."""
day_offset, hour_offset = int(day_offset), int(hour_offset)
offset_day = (ts + timedelta(days=day_offset, hours=hour_offset)).date()
return str(offset_day)
class CustomPrestoTemplateProcessor(PrestoTemplateProcessor):
"""A custom presto template processor."""
engine = "presto"
def process_template(self, sql: str, **kwargs) -> str:
"""Processes a sql template with $ style macro using regex."""
# Add custom macros functions.
macros = {
"DATE": partial(DATE, datetime.utcnow())
} # type: Dict[str, Any]
# Update with macros defined in context and kwargs.
macros.update(self.context)
macros.update(kwargs)
def replacer(match):
"""Expand $ style macros with corresponding function calls."""
macro_name, args_str = match.groups()
args = [a.strip() for a in args_str.split(",")]
if args == [""]:
args = []
f = macros[macro_name[1:]]
return f(*args)
macro_names = ["$" + name for name in macros.keys()]
pattern = r"(%s)\s*\(([^()]*)\)" % "|".join(map(re.escape, macro_names))
return re.sub(pattern, replacer, sql)
CUSTOM_TEMPLATE_PROCESSORS = {
CustomPrestoTemplateProcessor.engine: CustomPrestoTemplateProcessor
}
SQL Lab also includes a live query validation feature with pluggable backends.
You can configure which validation implementation is used with which database
engine by adding a block like the following to your config.py:

View File

@@ -104,6 +104,15 @@ environment using the configuration variable ``JINJA_CONTEXT_ADDONS``.
All objects referenced in this dictionary will become available for users
to integrate in their queries in **SQL Lab**.
Customize templating
''''''''''''''''''''
As mentioned in the `Installation & Configuration <https://superset.incubator.apache.org/installation.html#sql-lab>`__ documentation,
it's possible for administrators to overwrite Jinja templating with your customized
template processor using the configuration variable ``CUSTOM_TEMPLATE_PROCESSORS``.
The template processors referenced in the dictionary will overwrite default Jinja template processors
of the specified database engines.
Query cost estimation
'''''''''''''''''''''