在 Airflow DAG 中,当使用 Jinja 模板语法时,会出现文本被解析两次的情况。例如,下面的代码:
from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from datetime import datetime
dag = DAG(
'my_dag',
start_date=datetime(2019, 1, 1),
schedule_interval=None
)
my_task = BashOperator(
task_id='my_task',
bash_command='echo hello',
dag=dag
)
my_task_template = BashOperator(
task_id='my_task_template',
bash_command='echo {{ ds }} world',
dag=dag
)
在 my_task_template
中,我们使用了 Jinja 模板语法,将 ds
变量插入了一个字符串中。由于 Airflow 默认会将所有任务提交到 airflow
数据库中,而 {{ ds }}
又是一个有效的 Jinja 模板语法,因此字符串在提交到数据库时会被解析两次。
解决这个问题的一个方法是在模板中使用 {% raw %}
和 {% endraw %}
块将 Jinja 模板语法括起来,从而避免字符串被解析。例如,我们可以将上面的代码改写为:
from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from datetime import datetime
dag = DAG(
'my_dag',
start_date=datetime(2019, 1, 1),
schedule_interval=None
)
my_task = BashOperator(
task_id='my_task',
bash_command='echo hello',
dag=dag
)
my_task_template = BashOperator(
task_id='my_task_template',
bash_command='{% raw %}echo {{ ds }} world{% endraw %}',
dag=dag
)
这样,在提交到数据库时,字符串就不会被解析两次了。