Airflow 使用jinja模板中的气流连接

Airflow 使用jinja模板中的气流连接,airflow,Airflow,我试图使用环境变量将DB参数传递给BashOperator,但我找不到任何文档/示例来说明如何使用来自Jinja模板的连接 所以我在寻找类似于变量的东西 echo {{ var.value.<variable_name> }} echo{{var.value.} 气流不提供此类宏。 但是,您可以创建自定义宏来解决此问题 连接示例: 创建宏: def get_host(conn_id): connection = BaseHook.get_connection(conn_i

我试图使用环境变量将DB参数传递给BashOperator,但我找不到任何文档/示例来说明如何使用来自Jinja模板的连接

所以我在寻找类似于变量的东西

echo {{ var.value.<variable_name> }}
echo{{var.value.}

气流不提供此类宏。 但是,您可以创建自定义宏来解决此问题

连接示例:

创建宏:

def get_host(conn_id):
    connection = BaseHook.get_connection(conn_id)
    return connection.host

def get_schema(conn_id):
    connection = BaseHook.get_connection(conn_id)
    return connection.schema

def get_login(conn_id):
    connection = BaseHook.get_connection(conn_id)
    return connection.login
在DAG中使用它们:

def print_function(**context):
    print(f"host={context['host']} schema={context['schema']} login={context['login']}")

user_macros = {
    'get_host': get_host,
    'get_schema': get_schema,
    'get_login': get_login,
}

with DAG(
    dag_id='connection',
    default_args=default_args,
    schedule_interval=None,
    user_defined_macros=user_macros,
) as dag:

# Example how to use as function
python_op = PythonOperator( 
    task_id='python_task',
    provide_context=True,
    python_callable=print_function,
    op_kwargs={
        'host': get_host("test_conn"),
        'schema': get_schema("test_conn"),
        'login': get_login("test_conn"),
    }
)

# Example how to use as Jinja string
bash_op = BashOperator( 
    task_id='bash_task',
    bash_command='echo {{ get_host("test_conn") }} {{ get_schema("test_conn") }} {{ get_login("test_conn") }} ',
)
PythonOperator的渲染示例:

bash操作符的渲染
示例:

一般解释: 此代码所做的是创建一个自定义函数
func()
,用作
用户定义的\u宏
,从而提供使用它的能力,就像此宏是由自身定义的一样。 可以通过以下方式访问模板:
{{func()}
,如示例中所示,函数allow accept参数

注意您可以为连接对象中的所有字段创建此类函数


使用时要小心,以文本形式传递密码可能不是一个好主意。

改进之前的答案

按DAG定义宏:
{{conn.}
您可以使用以下宏获取
conn..host
语法:

class ConnectionGrabber:
    def __getattr__(self, name):
        return  Connection.get_connection_from_secrets(name)
dag = DAG(user_defined_macros={'connection': ConnectionGrabber()}

将名称
connection
注入到jinja模板上下文中,
connection
是一个
ConnectionGrabber
实例。此
ConnectionGrabber
提供动态/托管属性,因此当您请求属性
my\u conn\u id
(如
connection.my\u conn\u id
)时,它将使用
aiffort.models.connection.get\u connection\u from\u secrets
执行查找,从那里,您可以使用
a.m.Connection
属性,如
host
login
密码

在jinja模板中使用
bash_command='echo{{{connection.mssql.host}}'
访问连接
mssql
的完整示例:

from airflow.models import DAG,Connection
from airflow.operators.bash import BashOperator
from airflow.utils.dates import days_ago


class ConnectionGrabber:
    def __getattr__(self, name):
        return  Connection.get_connection_from_secrets(name)


args = {'owner': 'airflow', 'retries': 3, 'start_date': days_ago(2)}

dag = DAG(
    dag_id='test_connection',
    default_args=args,
    schedule_interval='0 0 * * *',
    dagrun_timeout=timedelta(minutes=60),
    user_defined_macros={'connection': ConnectionGrabber()}
)

task = BashOperator(task_id='read_connection', bash_command='echo {{connection.mssql.host }}', dag=dag)
在插件中定义宏:
{{macros.conn.value.}}
如果您想在所有DAG中使用此宏,可以将其封装在如下插件中:

# $AIRFLOW_HOME/plugins/connection_macro.py
from airflow.plugins_manager import AirflowPlugin
from airflow.models import Connection


class ConnectionGrabber:
    __name__ = "value"
    def __str__(self):
        return self.__name__
    def __getattr__(self, name):
        return  Connection.get_connection_from_secrets(name)

class MacrosPlugin(AirflowPlugin):
    name = "conn"
    macros = [ConnectionGrabber()]
检查插件是否可以加载
气流插件

airflow plugins
name | source                    | macros
=====+===========================+=======
conn | $PLUGINS_FOLDER/macros.py | value
然后可以在jinja模板中使用
{{macros.conn.value..host}
,如下所示

   task = BashOperator(task_id='read_connection', bash_command='echo macros.conn.value.mssql.host = {{macros.conn.value.mssql.host }}', dag=dag)
我还打开了一个对话框来添加
conn.value.
语法