为何Airflow BashOperator调用单日期范围API却获取多日数据?
问题描述
我正在学习Apache Airflow,创建了一个简单的DAG用于从REST API获取每日事件数据。直接在浏览器中调用API:http://localhost:5000/events?start_date=2019-01-01&end_date=2019-01-02时,它正确返回单日数据:
[ { "date": "2019-01-01", "user": "user1" } ]
但使用Airflow BashOperator调用相同API URL时,输出文件却包含2019-01-01至2019-01-05的数据,不符合预期。相关代码如下:
dag = DAG( dag_id="04_time_delta", schedule_interval='@daily', start_date=dt.datetime(2026,1,1) ) fetch_events = BashOperator( task_id ='fetch_events', bash_command=( "mkdir -p /Users/asadali/data/events && " "curl -o /Users/asadali/data/events/events.json http://localhost:5000/events?" "start_date=2019-01-01&" "end_date=2019-01-02" ), dag = dag ) fetch_events
问题原因
问题出在BashOperator的bash_command里的&符号——在bash语法中,&是用来将命令放到后台执行的分隔符,这就导致你的curl命令被拆成了两部分:
curl -o /Users/asadali/data/events/events.json http://localhost:5000/events?start_date=2019-01-01end_date=2019-01-02
API只接收到了start_date参数,没有收到end_date,所以返回了默认范围内(2019-01-01至2019-01-05)的数据。
解决方法
有两种可行的修改方式:
- 方式一:用单引号包裹整个URL,避免bash解析
&符号:
fetch_events = BashOperator( task_id ='fetch_events', bash_command=( "mkdir -p /Users/asadali/data/events && " "curl -o /Users/asadali/data/events/events.json 'http://localhost:5000/events?start_date=2019-01-01&end_date=2019-01-02'" ), dag = dag )
- 方式二:对
&进行转义,写成\&:
fetch_events = BashOperator( task_id ='fetch_events', bash_command=( "mkdir -p /Users/asadali/data/events && " "curl -o /Users/asadali/data/events/events.json http://localhost:5000/events?" "start_date=2019-01-01\&" "end_date=2019-01-02" ), dag = dag )
另外补充:你的DAG start_date设置为2026年,这会导致DAG不会自动触发执行(除非手动触发),如果是测试用例可以忽略,但实际生产场景建议设置为过去的日期。
内容的提问来源于stack exchange,提问作者user18832520
相关产品推荐
相关产品推荐

