在Apache Airflow中的S3KeySensor中模板化`bucket_key`

时间:2018-05-24 16:28:02

标签: jinja2 airflow

Airflow版本:1.9.0

在气流dag文件中,我有一个名为PythonOperator的{​​{1}}任务,它在python_callable函数中设置以下xcom变量:

run_query

在同一个dag中,我有一个kwargs['ti'].xcom_push(key='query_result_loc', value=query_result_loc)任务,它使用上面的位置作为其bucket_key参数:

S3KeySensor

现在,当我运行dag(在测试模式或trigger_dag模式下)时,S3KeySensor会抱怨缺少bucket_name,它来自S3KeySensor definition中的此代码:

S3KeySensor(task_id = 'check_file_in_s3',
                 bucket_key = '{{  ti.xcom_pull(task_ids="run_query",key="query_result_loc")  }}' ,
                 bucket_name = None,
                 wildcard_match = False,
                 poke_interval=60,
                 timeout=1200,
                 dag = dag
                 )

看起来模板在此阶段没有渲染。

如果我注释掉if,它可以正常工作。这是模板字段的错误还是错误用法?

更新,基于@ kaxil的评论:

  • 没有提供bucket_name,而且' if'阻止没有注释,气流甚至无法检测到dag。在用户界面上,我看到了这个错误: class S3KeySensor(BaseSensorOperator): """ Waits for a key (a file-like instance on S3) to be present in a S3 bucket. S3 being a key/value it does not support folders. The path is just a key a resource. :param bucket_key: The key being waited on. Supports full s3:// style url or relative path from root level. :type bucket_key: str :param bucket_name: Name of the S3 bucket :type bucket_name: str :param wildcard_match: whether the bucket_key should be interpreted as a Unix wildcard pattern :type wildcard_match: bool :param aws_conn_id: a reference to the s3 connection :type aws_conn_id: str """ template_fields = ('bucket_key', 'bucket_name') @apply_defaults def __init__( self, bucket_key, bucket_name=None, wildcard_match=False, aws_conn_id='aws_default', *args, **kwargs): super(S3KeySensor, self).__init__(*args, **kwargs) # Parse if bucket_name is None: parsed_url = urlparse(bucket_key) if parsed_url.netloc == '': raise AirflowException('Please provide a bucket_name') else: bucket_name = parsed_url.netloc if parsed_url.path[0] == '/': bucket_key = parsed_url.path[1:] else: bucket_key = parsed_url.path self.bucket_name = bucket_name self.bucket_key = bucket_key
  • 未提供bucket_name,但对' if'进行了以下修改。阻止(参见删除Broken DAG: [/XXXX/YYYY/project_airflow.py] Please provide provide a bucket_name检查),它工作正常:

    if parsed_url.netloc == ''
  • 提供了一个bucket_name,它可以在if bucket_name is None: parsed_url = urlparse(bucket_key) bucket_name = parsed_url.netloc if parsed_url.path[0] == '/': bucket_key = parsed_url.path[1:] else: bucket_key = parsed_url.path 标签下显示bucket_keybucket_name的呈现值。

2 个答案:

答案 0 :(得分:0)

您现在可能已经解决了这个问题,但这是因为您没有为task_ids提供数组。格式应为task_ids=["run_query"]。将其更改为此解决了我的问题。

答案 1 :(得分:0)

正如您在更新的引用中正确注意到的那样,存储桶密钥验证发生在 jinja 模板之前。

我找到的唯一解决方案是不使用仅提供存储桶密钥的功能。如果要使用模板,请同时提供存储桶名称和存储桶密钥。在这种情况下,不会进行验证并且字段将被模板化。