我有一个用例,其中Im在for循环内,并且需要动态填充HttpSensor任务中的字段
我尝试使用以下语法:
方法1失败:
s = 'sensor_task_sd_{0}'.format(d)
sensor_task_sd = HttpSensor(
task_id=s,
http_conn_id='ss_api',
endpoint="/rest/v1/pipeline/{{ti.xcom_pull(key='curr_ss_pipe_id', task_ids={})}}/status?rev=0".format(t),
request_params={'X-Requested-By': 'abc_123'},
response_check=lambda response: True if "FINISHED" in response.text else False,
poke_interval=10,
soft_fail=True,
timeout=600,
dag=dag_subdag,
)
但是失败,因为在这一行:
endpoint="/rest/v1/pipeline/{{ti.xcom_pull(key='curr_ss_pipe_id', task_ids={})}}/status?rev=0".format(t)
我无法使用.format(t)代替python字符串。
相反,如果我对某些值进行硬编码,则上面的代码可以工作...例如,下面的代码可以正常工作:
方法2成功:
s = 'sensor_task_sd_{0}'.format(d)
sensor_task_sd = HttpSensor(
task_id=s,
http_conn_id='ss_api',
endpoint="/rest/v1/pipeline/{{ti.xcom_pull(key='curr_ss_pipe_id', task_ids='start_pipeline_sd_campaignhistory')}}/status?rev=0",
request_params={'X-Requested-By': 'abc_123'},
response_check=lambda response: True if "FINISHED" in response.text else False,
poke_interval=10,
soft_fail=True,
timeout=600,
dag=dag_subdag)
我只是不明白这一点.....我尝试了各种技巧的组合来使其起作用,只是我并没有采用Iam用来保持代码动态的字符串插值。
所以我的问题很简单:
如何使HttpSensor操作符动态化?我不想在端点字符串(方法2样式)中对函数值进行硬编码,我想使用在运行时设置的值(方法1样式)。
如何使方法1起作用?
答案 0 :(得分:0)
因此,Airflow使用Jinja对其字符串进行模板化,并且当您混合Jinja模板化和Python格式时,您需要“转义” Jinja所需的花括号,以便Python格式不会占用它们。为此,您需要将每个.format()
调用以外的花括号加倍。
这应该为您提供所需的结果。
endpoint="/rest/v1/pipeline/{{{{ ti.xcom_pull(key='curr_ss_pipe_id', task_ids={}) }}}}/status?rev=0".format(t)
顺便说一句,以我使用f字符串(Python 3.6+)或命名格式参数的经验,如果您真的可以在将Airflow脚本中的二者混合使用时确实可以帮助提高代码清晰度。但是您仍然需要“转义”大括号。
f字符串:
endpoint=f"/rest/v1/pipeline/{{{{ ti.xcom_pull(key='curr_ss_pipe_id', task_ids={t})}} }}/status?rev=0"
命名格式参数:
endpoint="/rest/v1/pipeline/{{{{ ti.xcom_pull(key='curr_ss_pipe_id', task_ids={task_id}) }}}}/status?rev=0".format(task_id=t)
希望有帮助:)