web-dev-qa-db-fra.com

Comment créer une tâche conditionnelle dans Airflow

J'aimerais créer une tâche conditionnelle dans Airflow, comme décrit dans le schéma ci-dessous. Le scénario attendu est le suivant:

  • La tâche 1 s'exécute
  • Si la tâche 1 réussit, exécutez la tâche 2a.
  • Sinon si la tâche 1 échoue, alors exécutez la tâche 2b
  • Enfin exécuter la tâche 3

Conditional Task Toutes les tâches ci-dessus sont SSHExecuteOperator. J'imagine que je devrais utiliser ShortCircuitOperator et/ou XCom pour gérer la situation, mais je ne suis pas sûr de la manière de la mettre en œuvre. Pourriez-vous s'il vous plaît décrire la solution?

40
Alexis.Rolland

Vous devez utiliser règles de déclenchement du flux d'air

Tous les opérateurs ont un argument trigger_rule qui définit la règle selon laquelle la tâche générée est déclenchée.

Les possibilités de la règle de déclenchement:

ALL_SUCCESS = 'all_success'
ALL_FAILED = 'all_failed'
ALL_DONE = 'all_done'
ONE_SUCCESS = 'one_success'
ONE_FAILED = 'one_failed'
DUMMY = 'dummy'

Voici l'idée pour résoudre votre problème:

from airflow.operators.ssh_execute_operator import SSHExecuteOperator
from airflow.utils.trigger_rule import TriggerRule
from airflow.contrib.hooks import SSHHook

sshHook = SSHHook(conn_id=<YOUR CONNECTION ID FROM THE UI>)

task_1 = SSHExecuteOperator(
        task_id='task_1',
        bash_command=<YOUR COMMAND>,
        ssh_hook=sshHook,
        dag=dag)

task_2 = SSHExecuteOperator(
        task_id='conditional_task',
        bash_command=<YOUR COMMAND>,
        ssh_hook=sshHook,
        dag=dag)

task_2a = SSHExecuteOperator(
        task_id='task_2a',
        bash_command=<YOUR COMMAND>,
        trigger_rule=TriggerRule.ALL_SUCCESS,
        ssh_hook=sshHook,
        dag=dag)

task_2b = SSHExecuteOperator(
        task_id='task_2b',
        bash_command=<YOUR COMMAND>,
        trigger_rule=TriggerRule.ALL_FAILED,
        ssh_hook=sshHook,
        dag=dag)

task_3 = SSHExecuteOperator(
        task_id='task_3',
        bash_command=<YOUR COMMAND>,
        trigger_rule=TriggerRule.ONE_SUCCESS,
        ssh_hook=sshHook,
        dag=dag)


task_2.set_upstream(task_1)
task_2a.set_upstream(task_2)
task_2b.set_upstream(task_2)
task_3.set_upstream(task_2a)
task_3.set_upstream(task_2b)
36
Jean S

Airflow a un BranchPythonOperator qui peut être utilisé pour exprimer plus directement la dépendance de branchement.

Les docs décrivent son utilisation:

BranchPythonOperator ressemble beaucoup à PythonOperator sauf qu’il attend un python_callable qui retourne un task_id. Le task_id renvoyé est suivi et tous les autres chemins sont ignorés. Le task_id renvoyé par la fonction Python doit faire référence à une tâche directement en aval de la tâche BranchPythonOperator.

...

Si vous souhaitez ignorer certaines tâches, gardez à l’esprit que vous ne pouvez pas avoir un chemin vide, si c'est le cas, créez une tâche fictive.

Exemple de code

def dummy_test():
    return 'branch_a'

A_task = DummyOperator(task_id='branch_a', dag=dag)
B_task = DummyOperator(task_id='branch_false', dag=dag)

branch_task = BranchPythonOperator(
    task_id='branching',
    python_callable=dummy_test,
    dag=dag,
)

branch_task >> A_task 
branch_task >> B_task

[~ # ~] éditer [~ # ~] :

Si vous installez une version Airflow> = 1.10.3, vous pouvez également renvoyer une liste d'identifiants de tâches , ce qui vous permet de sauter plusieurs chemins en aval dans un seul opérateur et don ne pas utiliser une tâche factice avant de rejoindre .

42
villasv