Airflow 从调度间隔为@次的主dag触发外部dag的最佳方法?

Airflow 从调度间隔为@次的主dag触发外部dag的最佳方法?,airflow,airflow-operator,Airflow,Airflow Operator,拥有从主dag调用不同dag的任务列表。我正在使用TriggerDagrunoperator来完成此任务。但面临的问题很少 TriggerDagrunoperator不会等待外部dag的完成,它会触发下一个任务。我希望等待完成,然后根据状态触发下一个任务。遇到外部传感器。这使过程变得复杂。但是externaltasksensor的问题是,它只能按计划工作。当我使用externaltasksensor时,它在达到超时时间后失败 是否有办法从主dag顺序触发不同的dag,而不是并行触发。因此,只有在

拥有从主dag调用不同dag的任务列表。我正在使用TriggerDagrunoperator来完成此任务。但面临的问题很少

  • TriggerDagrunoperator不会等待外部dag的完成,它会触发下一个任务。我希望等待完成,然后根据状态触发下一个任务。遇到外部传感器。这使过程变得复杂。但是externaltasksensor的问题是,它只能按计划工作。当我使用externaltasksensor时,它在达到超时时间后失败
  • 是否有办法从主dag顺序触发不同的dag,而不是并行触发。因此,只有在先前触发的dag成功完成dag中的所有任务后,才会触发另一个dag

  • 使用<代码> TriggerDagrunoperator < /代码>触发DAG后,可以考虑调用<代码> DagSensor <代码>,等待DAG完成,然后触发其他天。下面是我们如何实现我们的版本(不是完美的,但完成了任务):

    以下是您如何称呼它:

    from airflow.operators import DagSensor
    check_my_dag_completion = DagSensor(
        dag=dag,
        task_id='check_my_dag_completion',
        external_dag_id='my_dag',
        poke_interval=30,
        timeout=3600
    )
    
    这意味着您的工作流中可以有类似的内容:

    call_dag_a >> check_dag_a >> call_dag_b >> check_dag_b
    

    触发外部dag后运行此任务:

    import time
    from airflow.models import DagRun
    from airflow import AirflowException
    from airflow.operators.python_operator import PythonOperator
    
    def get_external_dag_status(dag_id,**kwargs):
        dag_id = dag_id 
        dag_runs = DagRun.find(dag_id=dag_id)
        for dag_run in dag_runs:
          #print("state = "+dag_run.state)
          res1 = dag_run.state
          #print(dag_run)
        return res1
    
    def check_status(dag_id,**kwargs):
      st = get_external_dag_status(dag_id)
      while st != 'success':
        if st == 'failed':
          print(st)
          break
        time.sleep(300) #optional if need to check for every 5 minutes 
        st = get_external_dag_status(dag_id)
      if st == 'success':
        return st
      elif st == 'failed':
        raise ValueError('Dag Failed')
    
    status_check = PythonOperator(task_id="dag_check",
                             python_callable=check_status,
                             op_kwargs={'dag_id':'your external dag id'},
                             dag=spark_dag
                             )
    

    谢谢气流传感器中是否有DAG传感器?如何将dag传感器导入到现有代码中?dag传感器是我们实现的。您需要将代码保存到plugins/dag_sensor.py中。在你的airflow.cfg中有一个plugin_文件夹,你只需要确保它是正确的。除了添加我们自己的插件,有没有办法通过airflow中的可用功能实现上述功能。据我所知,没有。但这就是airflow的优点,你可以扩展它。单独使用任务传感器是不合适的。[1]我认为ExternalTaskSensor不需要时间表;对于您的用例,您可以跳过传递
    external\u task\u id
    &只传递
    execution\u date
    execution\u delta
    。这样,它将有效地充当
    ExternalDagSensor
    [2]我所知道的另一个棘手的解决方法:
    SubDagOperator
    。检查线程我尝试了您所述的方法,即使dag已成功运行,dag传感器仍处于运行状态。以下是供您参考的参数
    sensor\u run\u initial=externaltaskssensor(task\u id='dag\u sensor\u for\u run\u initial',external\u dag\u id='RunInitial',external\u task\u id=None,dag=dag)
    请告诉我是否需要更改externaltasksensor中的任何内容。是的,我承认它无法在开箱即用的情况下工作。您必须通过
    execution\u delta
    而不是
    execution\u date
    @y2k shubham尝试执行detla,即使外部dag成功运行,dag传感器仍保持运行状态
    sensor\u run\u initial=externaltaskssensor(task\u id='dag\u sensor\u for\u run\u initial',external\u dag\u id='RunInitial',external\u task\u id=None,execution\u delta=timedelta(分钟=30),dag=dag)
    。我希望这些参数是你建议的
    import time
    from airflow.models import DagRun
    from airflow import AirflowException
    from airflow.operators.python_operator import PythonOperator
    
    def get_external_dag_status(dag_id,**kwargs):
        dag_id = dag_id 
        dag_runs = DagRun.find(dag_id=dag_id)
        for dag_run in dag_runs:
          #print("state = "+dag_run.state)
          res1 = dag_run.state
          #print(dag_run)
        return res1
    
    def check_status(dag_id,**kwargs):
      st = get_external_dag_status(dag_id)
      while st != 'success':
        if st == 'failed':
          print(st)
          break
        time.sleep(300) #optional if need to check for every 5 minutes 
        st = get_external_dag_status(dag_id)
      if st == 'success':
        return st
      elif st == 'failed':
        raise ValueError('Dag Failed')
    
    status_check = PythonOperator(task_id="dag_check",
                             python_callable=check_status,
                             op_kwargs={'dag_id':'your external dag id'},
                             dag=spark_dag
                             )