在运行时在Airflow operator中创建和使用连接

在运行时在Airflow operator中创建和使用连接,airflow,Airflow,注意:这不是一个副本 我必须从我的DAG触发远程系统的某些任务。实现这一目标的直接方法是 问题在于远程系统是一个EMR集群,它本身是由上游任务在运行时使用创建的。因此,虽然我可以获得已启动的EMR集群的作业流id,但我需要的是将一个消息传递给每个下游任务 查看and,很明显,Airflow将尝试使用db中的conn_id和环境变量查找此连接,因此现在问题归结为能够在运行时从运算符中设置这两个属性之一 这似乎是一个相当常见的问题,因为如果无法实现,那么EmrCreateJobFlowOperato

注意:这不是一个副本

我必须从我的DAG触发远程系统的某些任务。实现这一目标的直接方法是

问题在于远程系统是一个EMR集群,它本身是由上游任务在运行时使用创建的。因此,虽然我可以获得已启动的EMR集群的作业流id,但我需要的是将一个消息传递给每个下游任务

查看and,很明显,Airflow将尝试使用db中的conn_id和环境变量查找此连接,因此现在问题归结为能够在运行时从运算符中设置这两个属性之一

这似乎是一个相当常见的问题,因为如果无法实现,那么EmrCreateJobFlowOperator的实用性将受到严重阻碍;但我没有遇到任何例子来证明这一点

是否可以在气流操纵器内创建和销毁这两个部件? 持续存在于气流的db中 环境变量应该可以被所有下游任务访问,而不仅仅是当前任务 如果没有,我有什么选择? 我在

气流v1.10 Python 3.6.6 如果需要,可以升级emr-5.15
执行此操作的方法是在EmrCreateJobFlowOperator之后创建气流任务,它使用BashOperator可能使用aws cli检索要运行任务的虚拟机的IP地址,并在同一个任务中运行airflow cli,该cli使用该IP地址创建SSH连接。

执行此操作的方法是在EmrCreateJobFlowOperator之后创建airflow任务,它使用BashOperator可能使用aws cli检索要在其中运行任务的虚拟机的IP地址,并在同一任务中运行使用该IP地址创建SSH连接的cli。

连接来自ORM 是的,您可以在运行时创建连接,即使是在DAG创建时,如果您足够小心的话。气流在其内部模型上是完全透明的,所以您可以直接与底层SqlAlchemy交互。如中最初所示,它非常简单:

from airflow.models import Connection
from airflow import settings

def create_conn(username, password, host=None):
    new_conn = Connection(conn_id=f'{username}_connection',
                                  login=username,
                                  host=host if host else None)
    new_conn.set_password(password)

    session = settings.Session()
    session.add(new_conn)
    session.commit()
当然,您可以在其中与EMR连接可能需要的任何其他额外连接属性进行交互

环境是有过程限制的 这不是Airflow或Python的限制,而是每个主要操作系统环境的AFAIK都与进程的生命周期有关。例如,当您在bash中导出变量时,您只是简单地声明,当您生成子进程时,您希望将该变量复制到子进程的环境中。这意味着父进程在创建后不能更改子进程的环境,子进程也不能更改父进程的环境

简言之,只有流程本身可以在创建后更改其环境。考虑到辅助进程是气流子进程,也很难控制其环境的创建。您可以做的是将环境变量写入一个文件,并在每次任务启动时使用该文件中的覆盖来有意更新当前环境。

连接来自ORM 是的,您可以在运行时创建连接,即使是在DAG创建时,如果您足够小心的话。气流在其内部模型上是完全透明的,所以您可以直接与底层SqlAlchemy交互。如中最初所示,它非常简单:

from airflow.models import Connection
from airflow import settings

def create_conn(username, password, host=None):
    new_conn = Connection(conn_id=f'{username}_connection',
                                  login=username,
                                  host=host if host else None)
    new_conn.set_password(password)

    session = settings.Session()
    session.add(new_conn)
    session.commit()
当然,您可以在其中与EMR连接可能需要的任何其他额外连接属性进行交互

环境是有过程限制的 这不是Airflow或Python的限制,而是每个主要操作系统环境的AFAIK都与进程的生命周期有关。例如,当您在bash中导出变量时,您只是简单地声明,当您生成子进程时,您希望将该变量复制到子进程的环境中。这意味着父进程在创建后不能更改子进程的环境,子进程也不能更改父进程的环境


简言之,只有流程本身可以在创建后更改其环境。考虑到辅助进程是气流子进程,也很难控制其环境的创建。您可以做的是将环境变量写入一个文件,并在每次任务开始时故意使用该文件中的覆盖来更新当前环境。

以下是在Airflow创建连接对象时对我的查询的回复,但我的下游任务是否能够仅使用康涅狄格州?我想我可能得做点什么,但说实话:我真的不知道SQLAlchemy和Airflow一起在幕后发挥的魔力。我也害怕撞到墙,就像是的,他们会的。与任何其他气流模型一样,连接可以保存在气流数据库中。它们可以在以后的钩子中由conn_id检索。@villasv我不在下面
仅仅实例化一个连接对象如何在Airflow的meta db中创建一个条目?我们不需要执行会话。添加。。像这样坚持下去?和类似的会话。删除。。要删除连接吗?你也有很好的洞察力。我将编辑答案以使其更完整。创建连接对象是可以的,但我的下游任务能否仅使用conn_id引用它?我想我可能得做点什么,但说实话:我真的不知道SQLAlchemy和Airflow一起在幕后发挥的魔力。我也害怕撞到墙,就像是的,他们会的。与任何其他气流模型一样,连接可以保存在气流数据库中。它们可以在后面的钩子中通过conn_id检索。@villasv我不明白仅仅实例化一个连接对象如何在Airflow的meta db中创建一个条目?我们不需要执行会话。添加。。像这样坚持下去?和类似的会话。删除。。要删除连接吗?你也有很好的洞察力。我将编辑答案使其更完整。我认为这是最干净的,但不是最简单的解决方案。我认为这是最干净的,但不是最简单的解决方案。