繁体   English   中英

Airflow / Composer-在zip打包的DAG中找不到模板

[英]Airflow/Composer - template not found in zip packaged DAG

我无法让模板化的SQL文件在Composer中工作。 我认为问题与以下事实有关:我将DAG打包为zip文件,以便包含其他代码。

我从这里开始(仅显示相关部分):

dag = DAG('my_dag',
      default_args=default_args,
      schedule_interval=schedule_interval)

task0 = BigQueryOperator(
     task_id='task0',
     use_legacy_sql=False,
     bql='sql/query_file.sql',
     bigquery_conn_id=bigquery_conn_id,
     dag=dag)

文件结构如下所示:

/dags/my_dag_file.py
/dags/sql/query_file.sql
/dags/my_pkg/
/dags/my_pkg/__init__.py
/dags/my_pkg/extra_module.py

我像这样压缩它,并将其复制到Composer dags文件夹中:

zip -r my_zip_file.zip *.py my_pkg/ sql/

这在本地有效,但在Composer上部署时却出现错误:

TemplateNotFound: sql/query_file.sql

我确定我在压缩包中包含了SQL文件。 我也尝试将其移动到根文件夹(无sql /子目录),但得到了相同的结果。

我读到某个地方,在实例化DAG对象时需要设置template_searchpath 我无法成功完成此操作。 当我尝试相对路径( sql )时,出现更多TemplateNotFound错误。 当我尝试如下所示的绝对路径时, not a directory

这是我尝试过的:

dag = DAG('my_dag',
      default_args=default_args,
      schedule_interval=schedule_interval,
      template_searchpath = os.path.dirname(__file__) + "/sql"
)

task0 = BigQueryOperator(
     task_id='task0',
     use_legacy_sql=False,
     bql='query_file.sql',
     bigquery_conn_id=bigquery_conn_id,
     dag=dag)

我还尝试将“ sql”作为任务路径的一部分,而不是模板的搜索路径,然后再次尝试将所有内容移至根级别,并得到相同的“非目录”错误。

据我所知,问题与文件包含在zip中有关。 __file__返回/home/airflow/gcs/dags/my_zip_file.zip/my_dag_file.py 但是然后os.listdir(os.path.dirname(__file__))抛出相同not a directory错误not a directory错误。 因此,也许是因为我们在zip归档文件中执行,所以我们不能以相同的方式使用文件夹和路径。 也许Jinja正在为此而绊倒...? 否则在打包zip文件时也许还有其他事情要做?

[2018-06-20 15:35:34,837] {base_task_runner.py:98} INFO - Subtask: Traceback (most recent call last):
[2018-06-20 15:35:34,838] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/bin/airflow", line 27, in <module>
[2018-06-20 15:35:34,840] {base_task_runner.py:98} INFO - Subtask:     args.func(args)
[2018-06-20 15:35:34,841] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/airflow/bin/cli.py", line 392, in run
[2018-06-20 15:35:34,841] {base_task_runner.py:98} INFO - Subtask:     pool=args.pool,
[2018-06-20 15:35:34,842] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/airflow/utils/db.py", line 50, in wrapper
[2018-06-20 15:35:34,843] {base_task_runner.py:98} INFO - Subtask:     result = func(*args, **kwargs)
[2018-06-20 15:35:34,843] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/airflow/models.py", line 1477, in _run_raw_task
[2018-06-20 15:35:34,844] {base_task_runner.py:98} INFO - Subtask:     self.render_templates()
[2018-06-20 15:35:34,844] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/airflow/models.py", line 1760, in render_templates
[2018-06-20 15:35:34,845] {base_task_runner.py:98} INFO - Subtask:     rendered_content = rt(attr, content, jinja_context)
[2018-06-20 15:35:34,847] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/airflow/models.py", line 2481, in render_template
[2018-06-20 15:35:34,848] {base_task_runner.py:98} INFO - Subtask:     return jinja_env.get_template(content).render(**context)
[2018-06-20 15:35:34,849] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/jinja2/environment.py", line 812, in get_template
[2018-06-20 15:35:34,849] {base_task_runner.py:98} INFO - Subtask:     return self._load_template(name, self.make_globals(globals))
[2018-06-20 15:35:34,850] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/jinja2/environment.py", line 774, in _load_template
[2018-06-20 15:35:34,851] {base_task_runner.py:98} INFO - Subtask:     cache_key = self.loader.get_source(self, name)[1]
[2018-06-20 15:35:34,852] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/jinja2/loaders.py", line 171, in get_source
[2018-06-20 15:35:34,854] {base_task_runner.py:98} INFO - Subtask:     f = open_if_exists(filename)
[2018-06-20 15:35:34,855] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/jinja2/utils.py", line 151, in open_if_exists
[2018-06-20 15:35:34,856] {base_task_runner.py:98} INFO - Subtask:     return open(filename, mode)
[2018-06-20 15:35:34,856] {base_task_runner.py:98} INFO - Subtask: IOError: [Errno 20] Not a directory: '/home/airflow/gcs/dags/my_zip_file.zip/sql/query_file.sql'

它看起来像气流目前(截至1.10版本) 从拉链的DAG支持装载模板,因为它仅使用jinja2.FileSystemLoader加载它们(见DAG#get_template_env )。

首先,确认ZIP中的文件结构符合预期。

然后,尝试尝试获取路径:

os.path.join(os.path.dirname(os.path.realpath(__file__)),"sql","query_file.sql")

这就是我们在Airflow部署中获取查询路径的方式。

使用文件的绝对路径更安全,例如sql = os.path.abspath(os.path.join(os.path.dirname(__file__), "sql/query_file.sql"))

因为Airflow操作员/任务可能在新创建的临时目录下运行您的命令/方法,该临时目录不会复制您的依赖项。 查看Airflow Github上实现示例 ,您将了解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM