在传递带有${}变量的hql脚本时,似乎支持这一点,并在实际执行模板呈现的阶段之前对其进行预处理,将其转换为{}jinja样式,然后用用户提供的字典中的值替换这些值。我之所以相信这一点,是因为在hiveoperator类中有这样一个函数:
def prepare_template(self):
if self.hiveconf_jinja_translate:
self.hql = re.sub(
"(\$\{([ a-zA-Z0-9_]*)\})", "{{ \g<2> }}", self.hql)
if self.script_begin_tag and self.script_begin_tag in self.hql:
self.hql = "\n".join(self.hql.split(self.script_begin_tag)[1:])
问题是我不知道如何触发这段代码在模板呈现阶段之前被调用。我有这样一个基本的dag脚本:
from airflow import DAG
from airflow.operators.hive_operator import HiveOperator
from datetime import datetime, timedelta
default_args = dict(
owner='mpetronic',
depends_on_past=False,
start_date=datetime(2017, 5, 2),
verbose=True,
retries=1,
retry_delay=timedelta(minutes=5)
)
dag = DAG(
dag_id='report',
schedule_interval='* * * * *',
user_defined_macros=dict(a=1, b=2),
default_args=default_args)
hql = open('/home/mpetronic/repos/airflow/resources/hql/report.hql').read()
task = HiveOperator(
task_id='report_builder',
hive_cli_conn_id='hive_dv',
schema='default',
mapred_job_name='report_builder',
hiveconf_jinja_translate=True,
dag=dag,
hql=hql)
我可以看到,我的用户定义的宏字典使它与一个全局jinja上下文字典合并,然后应用到我的hql脚本,将其作为模板呈现。但是,因为我的hql是本地hql,所以我要更新的所有变量都是${}的形式,jinja只是跳过它们。我需要先调用prepare\u template(),但不知道如何实现。
我意识到我可以手动地将我的hql${}改为{{}},但这看起来像是一种反模式。我希望脚本能够工作本机或通过气流。这是taskinstance类中的函数,用于呈现手动更改的{}}值:
def render_templates(self):
task = self.task
jinja_context = self.get_template_context()
if hasattr(self, 'task') and hasattr(self.task, 'dag'):
if self.task.dag.user_defined_macros:
jinja_context.update(
self.task.dag.user_defined_macros)
rt = self.task.render_template # shortcut to method
for attr in task.__class__.template_fields:
content = getattr(task, attr)
if content:
rendered_content = rt(attr, content, jinja_context)
setattr(task, attr, rendered_content)
1条答案
按热度按时间3pvhb19x1#
我解决了我的问题。这是注解方法中使用的正则表达式:
它不考虑以下形式的直线变量:
在模式中不考虑冒号。这种形式是使用直线在命名空间中定义配置单元变量的更标准的方法。要使这个jinja替换工作,您必须使用
${var_name}
但只能使用以下方法以直线方式定义变量:我认为气流应该完全支持
hivevar:var_name
当您使用beeline运行时,beeline是配置单元使用的首选客户端。