Airflow 气流中的执行日期:需要作为变量访问

Airflow 气流中的执行日期:需要作为变量访问,airflow,Airflow,我真的是这个论坛的新手。但我一直在玩气流,有一段时间,为我们的公司。对不起,如果这个问题听起来很愚蠢 我正在使用一堆bash操作符编写一个管道。 基本上,对于每个任务,我只想使用“curl”调用RESTAPI 这就是我的管道的样子(非常简化的版本): 如果您注意到我现在正在做current\u datetime=datetime\u obj.now(tz=tz.tzlocal()) 相反,我想要的是“执行日期” 如何直接使用“执行日期”并将其分配给python文件中的变量 我遇到了访问args的

我真的是这个论坛的新手。但我一直在玩气流,有一段时间,为我们的公司。对不起,如果这个问题听起来很愚蠢

我正在使用一堆bash操作符编写一个管道。 基本上,对于每个任务,我只想使用“curl”调用RESTAPI

这就是我的管道的样子(非常简化的版本):

如果您注意到我现在正在做
current\u datetime=datetime\u obj.now(tz=tz.tzlocal())
相反,我想要的是“执行日期”

如何直接使用“执行日期”并将其分配给python文件中的变量

我遇到了访问args的一般问题。 我们真诚地感谢您的帮助


感谢

PythonOperator构造函数接受“提供上下文”参数(请参阅)。如果这是真的,那么它会通过kwargs将许多参数传递到可调用的python_中。我相信,kwargs(行刑日期)是你想要的

大概是这样的:

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)

我不知道如何使用bash操作符,但您可以从这个问题开始:
bash操作符的
bash\u命令
参数是一个模板。您可以使用
execution\u date
变量作为
datetime
对象访问任何模板中的
execution\u date
。在模板中,可以使用任何
jinja2
方法对其进行操作

将以下内容用作
bash操作符
bash\u命令
字符串:

如果您只需要与执行日期等效的字符串,
ds
将返回一个日期戳(YYYY-MM-DD),
ds\u nodash
返回相同但不带破折号(yyyyymmdd)等。有关
宏的详细信息,请参阅


您的最终操作员将如下所示:

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

我认为您不能在任务实例之外使用上下文中的值分配变量,它们只在运行时可用。在气流中加载和执行dag时,基本上有两个不同的步骤:

  • 首先解释和解析dag文件。它必须工作和编译,任务定义必须正确(没有语法错误或任何东西)。在此步骤中,如果进行函数调用以填充某些值,则这些函数将无法访问airflow上下文(例如,执行日期,如果正在执行某些回填操作,则更是如此)

  • 第二步是执行dag。只有在第二个步骤中,气流(
    执行日期、ds等…
    )提供的变量才可用,因为它们与dag的执行相关

因此,您无法使用气流上下文初始化全局变量,但是,气流为您提供了多种机制来实现相同的效果:

  • 在命令中使用jinja模板(可以是代码中的字符串,也可以是文件,两者都将被处理)。您在此处有可用模板的列表:。请注意,还提供了一些函数,特别是用于计算日增量和日期格式的函数

  • 使用PythonOperator传递上下文(使用
    provide\u context
    参数)。这将允许您使用语法
    kwargs['
    
    这应该在操作符的execute()方法中

    要在
    PythonOperator的可调用函数中打印执行日期
    您可以在气流脚本中使用以下内容,还可以添加
    开始时间
    结束时间
    ,如下所示:

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

    我已经将DATETIME值转换为字符串,因为我需要在SQL查询中传递它。另外,我们也可以使用它。

    < P>您可以考虑SimuleHTTPercor。它对于HTTP请求非常简单。可以通过模板传递端点参数的ExcRealSudio。

    谢谢。用这种方法,我将有一个任务T1,它将是一个实例。PythonOperator的provide_context=true,它允许我使用kwargs['execution_date'],在这里我将设置并返回当前的_datetime='execution_date'。然后我创建我的任务t2:BashOperator:在其中我将拉取(使用XCOM)并使用我的变量。所以你看,我必须创建两个任务。这有点不性感;)我确定(我希望我是对的)有一种方法可以直接在python代码中访问“execution_date”,而不必使用PythonOperator(如果你正在构建一个自定义操作符,这可能就是你想要的。我相信它可以用在/methods中,这是正确的答案。我只需要编辑它来显示任务的完整版本,例如
    t1=bash操作符(task_id='rest-api-1',bash_command='curl-XPOST'+hostname+':8000/run?st={execution_date}}',dag=dag)
    想用
    Python3
    fstrings信息更新此文件,
    command=f”““…”
    似乎不起作用。若要获得
    jinja2
    模板工作,我认为您不能使用
    fstrings
    如果我的dag每小时运行一次,并且当前我的dag的执行日期为2021-06-03 08:00:00,我使用{{execution_date}它返回的很好,但是我的问题是现在的时间是09:00:00,那么当我访问dag时,dag的执行日期将改变,或者在整个过程中保持不变。从技术上讲,有3种方法可以做到这一点,正如上面其他问题所指出的。使用jinja模板、在python_可调用中使用kwargs或使用上下文[“执行日期”]在操作员中。可能最好完全删除此答案,或者至少删除大部分答案。感谢大家的提醒,自从我写下此答案以来,我学到了很多关于气流的知识,我对其进行了编辑,使其更准确!我做了一些小的编辑,使您的第一个总结陈述与下面的两点一致。我认为此答案现在是c正确,尽管您可以添加更多代码示例以获得额外的分数。这是最正确的答案-问题是“如何使用‘执行日期’
    command = """curl -XPOST '%(hostname)s:8000/run?st={{ ds }}'""" % locals()
    t1 = BashOperator( task_id='rest-api-1', bash_command=command, dag=dag)
    
    def execute(self, context):
        execution_date = context.get("execution_date")
    
    def python_func(**kwargs):
        ts = kwargs["execution_date"]
        end_time = str(ts)
        start_time = str(ts.add(minutes=-30))