Airflow从2.2.2升级到2.8.1时触发ValueError参数顺序错误
问题分析
升级Airflow从2.2.2到2.8.1后,TaskFlow任务触发ValueError: non-default argument follows default argument错误,根源是新版本Airflow对TaskFlow函数的参数签名处理逻辑变更:当传入Jinja模板字符串(如task_date = "{{ ... }}")作为参数时,被内部识别为带默认值的参数,但原函数的所有参数均为无默认值的位置参数,导致参数顺序违反Python语法规则(非默认参数不能出现在默认参数之后)。
解决方案
有两种可行的修复方式,可根据实际场景选择:
方式1:利用Airflow上下文自动注入变量(推荐)
TaskFlow API支持自动注入Airflow上下文变量,无需手动传递Jinja模板字符串。直接在任务函数中声明logical_date参数,Airflow会自动传入当前DAG运行的逻辑日期,然后在函数内部计算前一天的日期:
from datetime import datetime, timedelta from airflow.decorators import task @task(multiple_outputs=True) def decorated_task( inputs: list[dict], project_id: str, bucket_name: str, logical_date: str, # Airflow自动注入上下文变量,格式为YYYY-MM-DD ) -> dict[str, str]: # 计算前一天的日期并转为ds_nodash格式(YYYYMMDD) task_date = (datetime.strptime(logical_date, "%Y-%m-%d") - timedelta(days=1)).strftime("%Y%m%d") # 执行原有业务逻辑 return {}
调用时不再需要手动传递logical_date参数:
decorated_task_result = decorated_task( inputs=inputs, project_id=PROJECT_ID, bucket_name=BUCKET_NAME, )
方式2:调整函数参数顺序,将带模板的参数后置并设默认值
如果必须保留外部传递模板字符串的方式,需将logical_date参数调整到所有无默认值参数之后,并设置默认值,符合Python参数语法规则:
from airflow.decorators import task @task(multiple_outputs=True) def decorated_task( inputs: list[dict], project_id: str, bucket_name: str, logical_date: str = "", # 后置并设置默认值 ) -> dict[str, str]: # 执行原有业务逻辑,使用传入的logical_date return {}
调用方式保持不变:
task_date = "{{ (dag_run.logical_date - macros.timedelta(days=1)) | ds_nodash }}" decorated_task_result = decorated_task( inputs=inputs, project_id=PROJECT_ID, bucket_name=BUCKET_NAME, logical_date=task_date, )
验证方法
修复后,重启Airflow调度器并刷新DAG页面,确认该DAG能正常解析且无报错。
内容的提问来源于stack exchange,提问作者Kevin Languasco
相关产品推荐
相关产品推荐

