web-dev-qa-db-ja.com

エアフローのexecution_date:変数としてアクセスする必要があります

私は本当にこのフォーラムの初心者です。しかし、私はしばらくの間、私たちの会社のために気流で遊んでいます。この質問が本当に馬鹿げているようであればごめんなさい。

一連のBashOperatorsを使用してパイプラインを作成しています。基本的に、タスクごとに、 'curl'を使用してREST apiを呼び出すだけです。

これは私のパイプラインのようです(非常に単純化されたバージョン):

from airflow import DAG
from airflow.operators import BashOperator, PythonOperator
from dateutil import tz
import datetime

datetime_obj = datetime.datetime

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime.datetime.combine(datetime_obj.today() - datetime.timedelta(1), datetime_obj.min.time()),
    'email': ['[email protected]'],
    'email_on_failure': True,
    'email_on_retry': False,
    'retries': 2,
    'retry_delay': datetime.timedelta(minutes=5),
}


current_datetime = datetime_obj.now(tz=tz.tzlocal())

dag = DAG(
    'test_run', default_args=default_args, schedule_interval=datetime.timedelta(minutes=60))

curl_cmd='curl -XPOST "'+hostname+':8000/run?st='+current_datetime +'"'


t1 = BashOperator(
    task_id='rest-api-1',
    bash_command=curl_cmd,
    dag=dag)

あなたがcurrent_datetime= datetime_obj.now(tz=tz.tzlocal())をやっていることに気づいたら、代わりにここで欲しいのは 'execution_date'

'execution_date'を直接使用して、pythonファイルの変数に割り当てるにはどうすればよいですか?

引数にアクセスするというこの一般的な問題があります。どんな助けも本当に感謝します。

ありがとう

41
Roger

BashOperatorbash_commandargumentは、templateexecution_date変数を使用して、datetimeobjectとして任意のテンプレートのexecution_dateにアクセスできます。テンプレートでは、jinja2メソッドを使用して操作できます。

BashOperatorbash_commandstringとして次を使用します。

# pass in the first of the current month
some_command.sh {{ execution_date.replace(day=1) }}

# last day of previous month
some_command.sh {{ execution_date.replace(day=1) - macros.timedelta(days=1) }}

実行日と同等の文字列が必要な場合、dsは日付スタンプ(YYYY-MM-DD)を返し、ds_nodashはダッシュなし(YYYYMMDD)などで同じを返します。その他のmacrosApi Docs で利用可能です。


最終的な演算子は次のようになります。

command = """curl -XPOST '%(hostname)s:8000/run?st={{ ds }}'""" % locals()
t1 = BashOperator( task_id='rest-api-1', bash_command=command, dag=dag)
35
Erik Schuchmann

PythonOperatorコンストラクターは、 'provide_context'パラメーターを受け取ります( https://pythonhosted.org/airflow/code.html を参照)。 Trueの場合、多くのパラメーターをkwargsを介してpython_callableに渡します。 kwargs ['execution_date']はあなたが望むものだと思います。

このようなもの:

def python_method(ds, **kwargs):
    Variable.set('execution_date', kwargs['execution_date'])
    return

doit = PythonOperator(
    task_id='doit',
    provide_context=True,
    python_callable=python_method,
    dag=dag)

BashOperatorでそれを行う方法がわかりませんが、この問題から始めるかもしれません: https://github.com/airbnb/airflow/issues/775

24
Ziggy Eunicien

タスクインスタンスの外部のエアフローコンテキストからの値を変数に割り当てることはできないと思います。これらは実行時にのみ使用できます。基本的に、気流でDAGをロードして実行する場合、2つの異なるステップがあります。

  • まず、DAGファイルが解釈および解析されます。動作してコンパイルする必要があり、タスク定義が正しい必要があります(構文エラーなどはありません)。このステップ中に、いくつかの値を埋めるために関数呼び出しを行うと、これらの関数はエアフローコンテキストにアクセスできなくなります(たとえば、バックフィルを実行している場合は実行日です)。

  • 2番目のステップは、ダグの実行です。エアフローによって提供される変数(execution_date, ds, etc...)は、ダグの実行に関連しているため、この2番目のステップでのみ使用可能です。

そのため、Airflowコンテキストを使用してグローバル変数を初期化することはできませんが、Airflowは同じ効果を達成するための複数のメカニズムを提供します。

  1. コマンドでjinjaテンプレートを使用します(コード内の文字列またはファイル内にある場合があり、両方が処理されます)。利用可能なテンプレートのリストはこちらにあります: https://airflow.Apache.org/macros.html#default-variables 。特に日のデルタと日付のフォーマットを計算するために、いくつかの機能も使用できることに注意してください。

  2. コンテキストを(provide_context引数で)渡すPythonOperatorを使用します。これにより、kwargs['<variable_name']という構文で同じテンプレートにアクセスできます。必要な場合は、PythonOperatorから値を返すことができます。この値は、後でテンプレートで使用できるXCOM変数に格納されます。 XCOM変数へのアクセスには、次の構文を使用します。 https://airflow.Apache.org/concepts.html#xcoms

  3. 独自の演算子を記述する場合、contextの辞書を使用してエアフロー変数にアクセスできます。

12
Babcool
def execute(self, context):
    execution_date = context.get("execution_date")

これは、Operatorのexecute()メソッド内にある必要があります

9
l0n3r4ng3r

PythonOperatorの呼び出し可能関数内で実行日を出力するには、Airflowスクリプトで次を使用し、次のようにstart_timeおよびend_timeを追加することもできます。

def python_func(**kwargs):
    ts = kwargs["execution_date"]
    end_time = str(ts)
    start_time = str(ts.add(minutes=-30))

SQLクエリで渡す必要があるため、datetime値を文字列に変換しました。それ以外でも使用できます。

0

SimpleHttpOperator https://airflow.Apache.org/_api/airflow/operators/http_operator/index.html#airflow.operators.http_operator.SimpleHttpOperator を検討できます。 httpリクエストを作成するのはとても簡単です。あなたはテンプレートを介してエンドポイントパラメータでexecution_dateを渡すことができます。

0
gigkokman