In this article, I am going to show how to set up dependencies between two DAGs. Imagine that I have a DAG that dumps data from production databases and another DAG that aggregates the raw data and pushes the result into a reporting database.
I want the second DAG to run when the first one finishes, but I don’t want to move its tasks into the first DAG because that would make a mess in the configuration.
Airflow does not allow to set up dependencies between DAGs explicitly, but we can use Sensors to postpone the start of the second DAG until the first one successfully finishes.
To configure the sensor, we need the identifier of another DAG (we will wait until that DAG finishes). Additionally, we can also specify the identifier of a task within the DAG (if we want to wait for a single task). If we want to wait for the whole DAG we must set external_task_id = None.
from datetime import datetime from airflow import DAG from airflow.operators.dummy_operator import DummyOperator from airflow.sensors.external_task_sensor import ExternalTaskSensor dag = DAG('dependency_dag', description='DAG with sensor', schedule_interval='* * * * *', start_date=datetime(2019, 7, 10)) sensor = ExternalTaskSensor(task_id='dag_sensor', external_dag_id = 'another_dag_id', external_task_id = None, dag=dag, mode = 'reschedule') task = DummyOperator(task_id='some_task', retries=1, dag=dag) task.set_upstream(sensor)
By default, the sensor waits for the successful execution of the dependency on the current day. We can also specify the status and time delta, so it is possible to run a dependency when a DAG fails or run it every hour. For details, look at the allowed_states and execution_delta parameters in the documentation.
How to use sensors
The sensor is just another type of task, so I create a new DAG which begins with a sensor. In the default configuration, the sensor checks the dependency status every minute.
After I configure the sensor, I should specify the rest of the tasks in the DAG. As I wrote in the previous paragraph, we use sensors like regular tasks, so I connect the task with the sensor using the upstream/downstream operator. I do it in the last line: