在气流中,我想在每个星期一早上8点运行一个dag(execution_date当然应该是“当天星期一早上8点”)。为此工作流程设置的相关参数是:
start_date
:“2018-03-19”schedule_interval
:“0 8 * * MON”我希望每个星期一早上8点看到一个傻瓜跑。第一个是在19-03-2018上午8点运行,execution_date
= 2018-03-19-08-00-00等每个星期一。
然而事情并非如此:dag不会在19/03/18上午8点开始。这里解释了真实的行为,例如:https://stackoverflow.com/a/39620901/1510109或https://stackoverflow.com/a/48213964/1510109 行为是:在间隔的每一端(在我的情况下是每周),dag以execution_date =间隔的开始(即前一周)运行。这种行为显然是出于“ETL思维方式”(见上面的链接)。但这绝对不是我想要的。
我可以通过execution_date
= trigger_date
=现在(=当前星期一早上8点)在每个星期一早上08:00运行我的dag怎么办?
由于
答案 0 :(得分:4)
使用开始时间和execution_date示例获取quick look at my answer。
你希望每周一早上8点运行。
所以这部分将保持不变:
schedule_interval: '0 8 * * MON',
您希望它在2018-03-19首次运行,因为第一次运行发生在开始日期后的第一个完整计划周期结束时,您应该将开始日期更改为:
start_date: datetime(2018,03,12),
您将不得不忍受Airflow将在每个时段的开头命名您的DagRuns,并根据设置为间隔时段开始的execution_date
传递宏。相应地调整你的逻辑。
您的第一次投放将在2018-03-19T08:00:00.0Z
和execution_date
之后开始,每个其他宏依赖于它,而DagRun的名称将为2018-03-12T08:00:00.0Z
只要您了解execution_date
的期望,并且您没有尝试将您的时间从datetime.now()
开始,您的DAG将能够在运作中具有幂等性。您可以随意在任何my_execution_date = execution_date + datetime.timedelta(7)
或自定义运算符中创建PythonOperator
之类的新变量(从任务的上下文中获取execution_date),使用{{ (execution_date + macros.timedelta(7)).strftime('%Y%m%d') }}
或{{ macros.ds_add(ds, 7) }}
之类的模板语句,或使用next_execution_date
。
您甚至可以添加user_defined_macros
之类的dag级别{'dt':lambda d: d+datetime.timedelta(days=7)}
来启用{{ dt(execution_date) }}
。最近添加了user_defined_filters
,例如{'dt':lambda d: d+datetime.timedelta(days=7)}
启用{{ execution_date | dt }}
。 next_ds
和next_execution_date
对您的目的来说会更容易。
在考虑模板的同时,您也可以阅读内置的内容:http://jinja.pocoo.org/docs/2.10/templates/#builtin-filters
答案 1 :(得分:1)
这就是气流的行为方式,它总是在持续时间结束时运行。详细行为here和airflow faq。
但是为了以某种方式让它在本周运行,我们可以做的是操纵DAG的execution_date
。这可能是向datetime
对象添加7天(如果每周安排)或可能使用{{ next_execution_date }}
宏的形式。
同意只有在DAG中使用某种日期或由它触发依赖项时才可以这样做。
再说一遍,DAG仍按照正常行为运行。我们尝试做的只是在程序/ DAG中操纵date
。
args = { ....
'start_date': datetime.datetime(2018,3,18)
}
dag = DAG(...
schedule_interval = "@weekly"
)
# DAG would run on 3/25/2018 for week of 18th March
# but lets say we manipulate here
# {{ next_execution_date }} macro
# or add 7 days
# So basically we are running with date 3/25/2018 instead of 3/18/2018 for the week of 18th March
答案 2 :(得分:0)
对我来说,我是通过以下方式解决的:
{{ ds if dag_run.external_trigger or dag_run.is_backfill else macros.ds_add(ds, 1) }}
如果DAG由外部触发器运行,则不应更改ds
。
如果DAG是通过回填来运行的,则我们不应更改ds
。
如果已安排DAG,我们将使用宏将其增加一天。