如何从气流中的变量写入/读取时间戳?

时间:2018-09-13 09:29:51

标签: airflow

我正在使用:EXEC_DATE = '{{ macros.ds_add(ds, 1) }}'这给了我执行日期,而不是小时。 我希望能够将此值另存为YYYY-MM-DD HH:MM到名为process_last_run的变量中。

在运行开始时基本读取变量,并在dag结束时写入变量。该变量指示上一次dag的运行时间。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

Jinja中有一个{{ execution_date }}变量,可用于获取当前DAG运行的执行日期。

更多信息:Airflow - Macros

如果您要跟踪执行的开始时间或结束时间或特定任务实例的持续时间(以秒为单位),该信息将存储在TaskInstance模型中。

class TaskInstance(Base, LoggingMixin):
    ...
    start_date = Column(UtcDateTime)
    end_date = Column(UtcDateTime)
    duration = Column(Float)

https://github.com/apache/incubator-airflow/blob/4c30d402c4cd57dc56a5d9dcfe642eadc77ec3ba/airflow/models.py#L877-L879

此外,如果您想计算整个DAG的运行时间,则可以通过查询围绕这些字段的Airflow元数据数据库来获取特定DAG运行的时间。

如果您已经在Python代码中执行此操作,则也可以访问任务实例本身上的execution_date字段,而无需使用模板层。

变量

您可以读写气流变量like so

Variable.set('my_key', 'some value')
my_val = Variable.get('my_key')

您还可以对变量with the CLI执行CRUD操作。

统计

如果您发现自己经常使用诸如任务持续时间之类的统计信息,则可能要记住的另一件事是Airflow的StatsD集成,该集成在执行时收集有关Airflow本身的指标。您可以使用statsd_exporter将这些指标放入基于推送的系统(如StatsD本身)或基于拉式的系统(如Prometheus / Grafana)中。

答案 1 :(得分:1)

您可以使用宏execution_date执行此操作。但是,请注意,这是气流中的一个较差的概念。它表示计划的间隔时间段的开始。即使手动重新运行任务,它也不会在同一dag运行中更改。它在那里支持幂等数据更新。坦率地说,这是处理数据管道的最佳方法。在您的情况下,尽管您在其他地方说过,数据获取api需要一个开始日期并提供所有最新数据,但这不利于进行等幂处理,尽管您可以在指定的截止时间后丢弃数据。

因此,您可以只选择数据处理完成后的日期,然后将其存储以备后用。您可以将其存储到气流变量中。您可能会注意到,尽管如下所示,您离开日期命令的时间将晚于从开始日期开始对所有数据从process_data api调用中获取数据的最后时间。因此,如果您的处理步骤将处理后的数据的实际最后日期和时间作为stdout的最后一行输出(由BashOperator for xcom捕获),则可能会更好。

E.G。

from airflow.models import Variable, DAG
from datetime import datetime

def pyop_fun(**context):
  # You could have used execution_date here and in the next operator
  # to make the operator rerun safe.
  # date_string = context['execution_date'].strftime('%Y-%m-%d %H:%M')
  # But elsewhere you said your api is always giving you the up-to-the-minute data.
  # So maybe getting the date from the prior task would work better for you.
  Variable.set(
    'process_last_run',
    context['task_instance'].xcom_pull(task_ids='process_data')

with dag as DAG(…):
  pyop = PythonOperator(
    task_id='set_process_last_run',
    callable=pyop_fun,
    provide_context=True, …)
  shop = BashOperator(
    task_id='process_data',
    bash_command='''
      process_data "{{var.value.process_last_run}}";
      date -u +%Y-%m-%d\ %H:%M''',
    xcom_push=True, …)
  shop >> pyop

# Because the last output line of a BashOperator is pushed into xcom for that
# task id with the default key, it can be pulled by the PythonOperator and 
# stored in a variable.