Airflow 回填的dag运行不会显示在UI中

Airflow 回填的dag运行不会显示在UI中,airflow,airflow-scheduler,Airflow,Airflow Scheduler,我有一个项目开始于2018年,但为此我定期添加一些新的DAG。因此,我所有的DAG都有一个开始日期在2018年,一个计划间隔每天,但是一个赶上时间设置为False,因为当我现在添加一个新的DAG时,我不希望它从2018年起每天都运行(现在,也许我必须运行它所有这些天) 但是,大多数情况下,我希望它在添加日期之前运行几周。 我希望dag在开始日期和添加日期(我添加dag的日期)之间运行,并在dag树状视图UI中显示为白色圆圈,因此,我可以在过去两周内手动触发它。 但在这个视图中没有显示任何内容 所

我有一个项目开始于2018年,但为此我定期添加一些新的DAG。因此,我所有的DAG都有一个
开始日期
在2018年,一个
计划间隔
每天,但是一个
赶上时间
设置为False,因为当我现在添加一个新的DAG时,我不希望它从2018年起每天都运行(现在,也许我必须运行它所有这些天)

但是,大多数情况下,我希望它在添加日期之前运行几周。 我希望dag在
开始日期
添加日期
(我添加dag的日期)之间运行,并在dag树状视图UI中显示为白色圆圈,因此,我可以在过去两周内手动触发它。 但在这个视图中没有显示任何内容

所以,我手动运行回填(从命令行…UI中的回填界面会更好),但回填执行的所有运行都不会出现在UI中。因此,如果一次运行回填失败,我仍然无法从UI重新运行它

“未显示
开始日期
添加日期
之间可能的dag运行”是否为气流的预期行为?有没有办法克服这个问题?或者有没有更好的方法来处理这个用例:“添加一个DAG,并在过去的一些日期手动运行它。”


[编辑]程序运行失败 正如所提出的,解决方案可以是打开catchup,并将
start\u date
add\u date
之间的所有运行标记为成功(或失败,无论什么)

我的结局是这样的:

导入日期时间
从气流导入DAG
从afflow.operators.bash_operator导入bash operator
从airflow.utils.state导入状态
开始日期=datetime.datetime(2020,10,1,tzinfo=datetime.timezone.utc)
add_date=datetime.datetime.now(datetime.timezone.utc)
#仅使用一个任务定义DAG
将DAG(“测试跟踪”,计划跟踪间隔=“@daily”,跟踪=真,开始日期=开始日期)作为DAG:
Bash操作员(
任务\u id=“打印”,
bash_command=“echo{{ds}”
)
#对于开始日期和添加日期之间的所有日期,创建一个dagrun并将其标记为失败。
对于[start_date+datetime.timedelta(n)中的d,对于范围(int((add_date-start_date).days))中的n:
打印(“为”,d.isoformat()创建dagrun)
尝试:
dag.create_dagrun(run_id=“programmatical_fill_{}”.format(d.isoformat()),state=state.FAILED,execution_date=d,start_date=add_date,external_trigger=False)
例外情况除外,如e:
打印(“错误:”,e)
通过
如您所见,首先,您必须将dagrun创建嵌套在try-except块中,因为每次Airflow读取此文件时,它都会尝试在dagrun数据库中添加相同的条目,并且会因主键冲突而失败

这大致可行。我所有的跑步记录都会出现:

但是,我不能(重新)运行其中任何一个。 清除1时,我得到以下错误:

没有要清除的任务实例

我设法将其中一个标记为成功(将圆圈和正方形变为绿色),然后清除它,将DAG(圆圈)变为运行状态,但将任务变为
None
状态,它从不执行


[编辑]仅限最新操作员 从另一个伟大的想法,我给了一个尝试

导入日期时间
从气流导入DAG
从afflow.operators.bash_operator导入bash operator
从airflow.utils.state导入状态
从airflow.operators.latest\u only\u operator导入LatestOnly operator
开始日期=datetime.datetime(2020,10,1)
将DAG(“仅测试最新”,计划间隔=“@daily”,catchup=True,start\u date=start\u date”)作为DAG:
迟发算子(
task\u id=“最新过滤器”
)>>Bash操作员(
任务\u id=“打印”,
bash_command=“echo{{ds}”
)
结果(我已经手动重新运行了第一次运行):

优点:

  • 它实现了我想做的事情
缺点:

  • 它还需要一个操作员
  • 这是缓慢的引导。运行我的12个DAG大约需要5分钟,而第一个任务刚刚完成(我是不是用它来“回填”2年的日常工作?)
  • 您不能清除DAG,而只能清除LatestOnlyOperator下的第一个任务,否则它将继续阻止下游任务的执行

最后,在
catchup=False
选项可用之前,这个操作符似乎是一个老把戏,我不确定它的可持续性,因为已经讨论过反对它了。

我终于找到了一个合适的解决方案,灵感来自“编程DAG运行”的想法

错误消息指出,
没有要清除的任务实例
。 因此,解决方案是在创建DAG运行时创建任务实例

以下是我的工作解决方案:

导入日期时间
从气流导入DAG
从airflow.models导入TaskInstance
从afflow.operators.bash_operator导入bash operator
从airflow.utils.state导入状态
从afflow.utils.timezone导入解析
start_date=parse(datetime.datetime(2020,11,1).isoformat())
add_date=datetime.datetime(2020,11,8,tzinfo=datetime.timezone.utc)
#创建您的dag
将DAG(“测试任务实例”,计划间隔=“@daily”,catchup=False,开始日期=开始日期)作为DAG:
#及其任务
Bash操作员(
任务\u id=“打印”,
bash_command=“echo'{{{ti}}'>/tmp/{{{ds}”
)
#对于每个预期执行日期
对于dag.date\u范围内的d(dag.start\u date,end\u date=add\u date)[:-1]:
#如果没有DAG运行已经存在
如果dag.get_dagrun(d)为无:
#创建一个新的(将状态标记为跳过)
dagrun=dag.create_dagrun(run_id=“programmatical_fill_{}”.format(d.isoformat()),
state=state.SKIPPED,
执行日期=d,
- for d in dag.date_range(dag.start_date, end_date=add_date):
+ for d in dag.date_range(dag.start_date, end_date=add_date)[:-1]: