Airflow中catchup=true时,如何获取调度日期而非执行日期?
解决Airflow Catchup时传递调度逻辑日期的问题
这是个很常见的Airflow调度场景问题,我来给你捋清楚怎么解决:
首先要明确Airflow里两个关键日期变量的区别(尤其是2.2版本之后的变化):
- 调度逻辑日期:就是DAG本该运行的那个日期(比如你设置每日调度,1月10日的任务就算在1月12日catchup运行,它的逻辑日期还是1月10日)
- 实际执行日期:任务真正开始运行的日期(比如上面例子里的1月12日)
你的需求就是在catchup时传递调度逻辑日期,而不是实际执行日期,具体实现分两种情况:
1. Airflow 2.2及以上版本(推荐)
从Airflow 2.2开始,官方把日期变量做了更清晰的区分:
{{ logical_date }}:对应调度逻辑日期,是你需要的核心变量{{ ds }}:logical_date的字符串格式(YYYY-MM-DD),直接用这个最方便{{ execution_date }}:现在代表任务实际执行的日期,这不是你需要的
示例代码
比如用BashOperator调用脚本:
from airflow import DAG from airflow.operators.bash import BashOperator from datetime import datetime default_args = { 'start_date': datetime(2024, 1, 1), 'catchup': True } with DAG( 'daily_script_dag', default_args=default_args, schedule_interval='@daily' ) as dag: run_daily_script = BashOperator( task_id='execute_script', # 直接用{{ ds }}传递调度逻辑日期 bash_command='python /your/script/path.py --target-date {{ ds }}' )
如果是PythonOperator,你可以通过上下文获取或直接传递模板变量:
from airflow.operators.python import PythonOperator def run_script(**context): # 从上下文获取逻辑日期的字符串格式 target_date = context['ds'] # 执行你的脚本逻辑,比如调用外部脚本 import subprocess subprocess.run(['python', '/your/script/path.py', '--target-date', target_date]) python_task = PythonOperator( task_id='run_python_script', python_callable=run_script, provide_context=True )
2. Airflow 2.2以下版本
在旧版本中,execution_date就是调度逻辑日期,{{ ds }}是它的字符串格式,所以直接用{{ ds }}或者{{ execution_date.strftime('%Y-%m-%d') }}就可以,catchup时会自动对应到每个错过的调度日期。
关键说明
当catchup=True时,Airflow会为每个错过的调度周期生成独立的任务实例,每个实例的logical_date(旧版为execution_date)都会被设置为对应的调度日期,所以{{ ds }}会自动替换成你需要的那个日期,完全不需要额外的判断或处理。
内容的提问来源于stack exchange,提问作者Anmol Virmani
相关产品推荐
相关产品推荐

