Airflow 当作为Jinja模板变量传递时,sql\u路径无法读取sql文件

Airflow 当作为Jinja模板变量传递时,sql\u路径无法读取sql文件,airflow,Airflow,我正在尝试使用Jinja模板变量,而不是使用variable.get'sql_path',以避免每次扫描dag文件时都碰到DB 原始代码 import datetime import os from functools import partial from datetime import timedelta from airflow.models import DAG,Variable from airflow.contrib.operators.snowflake_operator impo

我正在尝试使用Jinja模板变量,而不是使用variable.get'sql_path',以避免每次扫描dag文件时都碰到DB

原始代码

import datetime
import os
from functools import partial
from datetime import timedelta
from airflow.models import DAG,Variable
from airflow.contrib.operators.snowflake_operator import SnowflakeOperator
from alerts.email_operator import dag_failure_email

SNOWFLAKE_CONN_ID = 'etl_conn'

tmpl_search_path = []
for subdir in ['business/', 'audit/', 'business/transform/']:
    tmpl_search_path.append(os.path.join(Variable.get('sql_path'), subdir))


def get_db_dag(
    *,
    dag_id,
    start_date,
    schedule_interval,
    max_taskrun,
    max_dagrun,
    proc_nm,
    load_sql
):

    default_args = {
        'owner': 'airflow',
        'start_date': start_date,
        'provide_context': True,
        'execution_timeout': timedelta(minutes=max_taskrun),
        'retries': 0,
        'retry_delay': timedelta(minutes=3),
        'retry_exponential_backoff': True,
        'email_on_retry': False,
    }


    dag = DAG(
        dag_id=dag_id,
        schedule_interval=schedule_interval,
        dagrun_timeout=timedelta(hours=max_dagrun),
        template_searchpath=tmpl_search_path,
        default_args=default_args,
        max_active_runs=1,
        catchup='{{var.value.dag_catchup}}',
        on_failure_callback=alert_email_callback,
    )


    load_table = SnowflakeOperator(
        task_id='load_table',
        sql=load_sql,
        snowflake_conn_id=SNOWFLAKE_CONN_ID,
        autocommit=True,
        dag=dag,
    )

    load_vcc_svc_recon

    return dag

# ======== DAG DEFINITIONS #

edw_table_A = get_db_dag(
    dag_id='edw_table_A',
    start_date=datetime.datetime(2020, 5, 21),
    schedule_interval='0 5 * * *',
    max_taskrun=3,  # Minutes
    max_dagrun=1,  # Hours
    load_sql='recon/extract.sql',
)
当我将Variable.get'sql_path'替换为Jinja模板{{var.value.sql_path}}并运行Dag时,它抛出了如下错误,无法从sql文件夹的子目录获取文件

tmpl_search_path = []
for subdir in ['bus/', 'audit/', 'business/snflk/']:
    tmpl_search_path.append(os.path.join('{{var.value.sql_path}}', subdir))
得到以下错误为
inja2.exceptions.TemplateNotFound:extract.sql

模板不会在DAG脚本中的任何地方呈现。通常,它们以操作符的形式呈现。因此,除非将tmpl_search_path的元素传递给某个模板化参数{{var.value.sql_path},否则将不会呈现

DAG的模板路径未模板化。这就是为什么不能将Jinja模板传递给它

我能想到的选择是

硬编码变量的值。在管道脚本中获取'sql_path'。 保存变量的值。在配置文件中获取'sql_path',然后从管道脚本中读取它。 将变量.get调用移出for循环。这将导致对数据库的请求减少三倍。
当我尝试以变量的形式给出时,得到'sql_path',它是有效的。。但我想避免使用变量来避免对每个scan@Kar当然,这是因为在这种情况下,您使用的是变量模型,而不是模板。你可能想读一读夯实在气流中的工作原理。