Je dois référencer une variable renvoyée par un BashOperator
. Je fais peut-être mal, alors pardonnez-moi s'il vous plaît. Dans mon task_archive_s3_file
, Je dois obtenir le nom du fichier à partir de get_s3_file
. La tâche affiche simplement {{ ti.xcom_pull(task_ids=submit_file_to_spark) }}
sous forme de chaîne au lieu de la valeur.
Si j'utilise le bash_command
, La valeur s'imprime correctement.
get_s3_file = PythonOperator(
task_id='get_s3_file',
python_callable=obj.func_get_s3_file,
trigger_rule=TriggerRule.ALL_SUCCESS,
dag=dag)
submit_file_to_spark = BashOperator(
task_id='submit_file_to_spark',
bash_command="echo 'hello world'",
trigger_rule="all_done",
xcom_Push=True,
dag=dag)
task_archive_s3_file = PythonOperator(
task_id='archive_s3_file',
# bash_command="echo {{ ti.xcom_pull(task_ids='submit_file_to_spark') }}",
python_callable=obj.func_archive_s3_file,
params={'s3_path_filename': "{{ ti.xcom_pull(task_ids=submit_file_to_spark) }}" },
dag=dag)
get_s3_file >> submit_file_to_spark >> task_archive_s3_file
Des modèles tels que {{ ti.xcom_pull(...) }}
ne peuvent être utilisés qu'à l'intérieur de paramètres prenant en charge les modèles, sinon ils ne seront pas rendus avant leur exécution. Voir le template_fields
et template_ext
attributs de PythonOperator et BashOperator .
Alors templates_dict
est ce que vous utilisez pour passer des templates à votre python opérateur:
def func_archive_s3_file(**context):
archive(context['templates_dict']['s3_path_filename'])
task_archive_s3_file = PythonOperator(
task_id='archive_s3_file',
dag=dag,
python_callable=obj.func_archive_s3_file,
provide_context=True, # must pass this because templates_dict gets passed via context
templates_dict={'s3_path_filename': "{{ ti.xcom_pull(task_ids='submit_file_to_spark') }}" })
Cependant, dans le cas de l'extraction d'une valeur XCom, une autre alternative consiste simplement à utiliser l'objet TaskInstance
mis à votre disposition via le contexte:
def func_archive_s3_file(**context):
archive(context['ti'].xcom_pull(task_ids='submit_file_to_spark'))
task_archive_s3_file = PythonOperator(
task_id='archive_s3_file',
dag=dag,
python_callable=obj.func_archive_s3_file,
provide_context=True,
J'ai voté à la fois la question et la réponse, mais je pense que cela peut être un peu plus clair pour les utilisateurs qui souhaitent simplement transmettre de petits objets de données entre des tâches PythonOperator
dans leurs DAG. Référencer cette question et cet exemple XCom m'a conduit à la solution suivante. Super simple:
from airflow.models import DAG
from airflow.operators.python_operator import PythonOperator
DAG = DAG(
dag_id='example_dag',
start_date=datetime.now(),
schedule_interval='@once'
)
def Push_function(**kwargs):
ls = ['a', 'b', 'c']
return ls
Push_task = PythonOperator(
task_id='Push_task',
python_callable=Push_function,
provide_context=True,
dag=DAG)
def pull_function(**kwargs):
ti = kwargs['ti']
ls = ti.xcom_pull(task_ids='Push_task')
print(ls)
pull_task = PythonOperator(
task_id='pull_task',
python_callable=pull_function,
provide_context=True,
dag=DAG)
Push_task >> pull_task
Je ne sais pas pourquoi cela fonctionne, mais ça marche. Quelques questions pour la communauté:
ti
ici? Comment est-ce construit en **kwargs
?provide_context=True
nécessaire pour les deux fonctions?Toute modification visant à clarifier cette réponse est la bienvenue!
Utilisé le même code et modifié params comme Startdate
etc.
import airflow
from datetime import datetime, timedelta
from airflow.models import DAG
from airflow.operators.python_operator import PythonOperator
args = {
'owner': 'Airflow',
'start_date': airflow.utils.dates.days_ago(2),
}
DAG = DAG(
dag_id='simple_xcom',
default_args=args,
# start_date=datetime(2019, 04, 21),
schedule_interval="@daily",
#schedule_interval=timedelta(1)
)
def Push_function(**context):
msg='the_message'
print("message to Push: '%s'" % msg)
task_instance = context['task_instance']
task_instance.xcom_Push(key="the_message", value=msg)
Push_task = PythonOperator(
task_id='Push_task',
python_callable=Push_function,
provide_context=True,
dag=DAG)
def pull_function(**kwargs):
ti = kwargs['ti']
msg = ti.xcom_pull(task_ids='Push_task',key='the_message')
print("received message: '%s'" % msg)
pull_task = PythonOperator(`enter code here`
task_id='pull_task',
python_callable=pull_function,
provide_context=True,
dag=DAG)
Push_task >> pull_task