Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 气流传感器卡住了_Python_Airflow - Fatal编程技术网

Python 气流传感器卡住了

Python 气流传感器卡住了,python,airflow,Python,Airflow,我正在尝试使用ExternalTaskSensor,但它无法插入另一个DAG的任务,该任务已经成功完成 在这里,第一个DAG“a”完成其任务,然后通过ExternalTaskSensor触发第二个DAG“b”。相反,它被困在戳一个.first_任务 第一个DAG: import datetime from airflow import DAG from airflow.operators.python_operator import PythonOperator dag = DAG(

我正在尝试使用ExternalTaskSensor,但它无法插入另一个DAG的任务,该任务已经成功完成

在这里,第一个DAG“a”完成其任务,然后通过ExternalTaskSensor触发第二个DAG“b”。相反,它被困在戳一个.first_任务

第一个DAG:

import datetime
from airflow import DAG
from airflow.operators.python_operator import PythonOperator

dag = DAG(
    dag_id='a',
    default_args={'owner': 'airflow', 'start_date': datetime.datetime.now()},
    schedule_interval=None
)

def do_first_task():
    print('First task is done')

PythonOperator(
    task_id='first_task',
    python_callable=do_first_task,
    dag=dag)
第二个DAG:

import datetime
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from airflow.operators.sensors import ExternalTaskSensor

dag = DAG(
    dag_id='b',
    default_args={'owner': 'airflow', 'start_date': datetime.datetime.now()},
    schedule_interval=None
)

def do_second_task():
    print('Second task is done')

ExternalTaskSensor(
    task_id='wait_for_the_first_task_to_be_completed',
    external_dag_id='a',
    external_task_id='first_task',
    dag=dag) >> \
PythonOperator(
    task_id='second_task',
    python_callable=do_second_task,
    dag=dag)

我错过了什么

ExternalTaskSensor
假设您依赖于dag运行中具有相同执行日期的任务

这意味着在您的情况下,DAG
a
b
需要按照相同的时间表运行(例如每天上午9:00或w/e)

否则,在实例化
外部任务传感器时,需要使用
执行增量
执行日期

以下是操作员内部的文档,有助于进一步澄清:

:参数执行_delta:与上一次执行的时间差
请看,默认值与当前任务的执行日期相同。
对于昨天,使用[positive!]datetime.timedelta(days=1)。任何一个
执行增量或执行日期可以传递给
ExternalTaskSensor,但不是两者都有。
:type execution_delta:datetime.timedelta
:param execution_date_fn:接收当前执行日期的函数
并返回要查询的所需执行日期。要么是执行,要么是三角洲
或者执行日期可以传递给ExternalTaskSensor,但不能同时传递两者。
:type execution\u date\u fn:callable

为了澄清我在这里看到的以及其他相关问题,DAG不一定要按照公认答案中所述的相同时间表运行。DAG也不需要有相同的
开始日期
。如果创建的
ExternalTaskSensor
任务没有
execution\u delta
execution\u date\u fn
,则两个DAG需要具有相同的执行日期。如果两个DAG具有相同的计划,则每个间隔中的计划运行将具有相同的执行日期。我不确定手动触发的计划DAG运行的执行日期

为了使本例起作用,dag
b
ExternalTaskSensor
任务需要一个
execution\u delta
execution\u date\u fn
参数。如果使用
execution\u delta
参数,则应使
b
的执行日期-
execution\u delta
=
a
的执行日期。如果使用
execution\u date\u fn
,则该函数应返回
a
的执行日期

如果您使用的是
TriggerDagRunOperator
,然后使用
ExternalTaskSensor
来检测dag何时完成,您可以使用
TriggerDagRunOperator
execution\u date
参数将主dag的执行日期传递给触发的dag,如
execution\u date={{execution_date}}
。那么两个dag的执行日期将是相同的,您不需要每个dag的计划相同,也不需要使用
execution_delta
execution_date\u fn
传感器参数


上述内容是在Airflow 1.10.9上编写和测试的,从Airflow v1.10.7开始,tomcm的答案是不正确的(至少对于这个版本)。如果外部DAG没有相同的时间表,则应使用执行增量或执行日期来确定外部DAG的日期和时间表。

从我的成功案例来看:

default_args = {
    'owner': 'xx',
    'retries': 2,
    'email': ALERT_EMAIL_ADDRESSES,
    'email_on_failure': True,
    'email_on_retry': False,
    'retry_delay': timedelta(seconds=30),
    # avoid stopping tasks after one day
    'depends_on_past': False,
}

dag = DAG(
    dag_id = dag_id,
    # get the datetime type value
    start_date = pendulum.strptime(current_date, "%Y, %m, %d, %H").astimezone('Europe/London').subtract(hours=1),
    description = 'xxx',
    default_args = default_args,
    schedule_interval = timedelta(hours=1),
    )

您可以等到任务自动触发成功。不要手动执行,开始日期会不同。

因此,如果
a
b
按照相同的计划运行,我不需要传递
execution\u delta
execution\u fn
,对吗?@Josherzberg我相当肯定这是正确的,b但是我已经有一段时间没有使用这个传感器了。你知道如何在日程设置为无的情况下监控Dag吗?
...
    external_sensor= ExternalTaskSensor(
            task_id='ext_sensor_task_update_model',
            external_dag_id='xxx',
            external_task_id='xxx'.format(log_type),
            # set the task_id to None because of the end_task
            # external_task_id = None,
            dag=dag,
            timeout = 300,
            )
...