dbt:sql_header宏限制与查询注释

时间:2020-07-20 20:48:49

标签: dbt

Dbt具有sql_header的配置设置,表面上是用于在运行时将udf注入模型语句中。不幸的是,似乎不支持调用宏。此外,此设置不会影响短暂的实现。我创建了一个名为sql_footer的设置,但是在sql语句的末尾有类似的限制。

合理地调整query_header code以支持注入除注释块之外的原始sql,例如在配置字典中添加执行布尔值?

  dbt/core/dbt/adapters/base/query_headers.py
  def add(self, sql: str) -> str:
    if not self.query_comment:
        return sql

    if self.append:
        # replace last ';' with '<comment>;'
        sql = sql.rstrip()
        if sql[-1] == ';':
            sql = sql[:-1]
            return '{}\n{} {} {};'.format(sql, block_start, self.query_comment.strip(), block_end)
            vs
            return '{}\n/* {} */;'.format(sql, self.query_comment.strip())

我了解对将sql注入sql的任何保留,我的用例是系统开发人员非常不愿与模型开发人员联系的系统级配置,并且最好通过cicd进行控制。我们的etl具有不同的实现,根据环境需要不同的登台筛选器。我宁愿注入一两行sql,而不必为每个实现复制模型。 例如:

dbt_project.yml
models:
  - foo:
      query_comment:
        comment: "{{ var('ops_filter', default_filter()) }}"
        executable: True
        append: True
stg_foo.sql
with source as (Select *
from {{ source('foo') }})
select id 
from source
### inject footer sql here ###
where $date_param between dbt_valid_to and dbt_valid_from
|where 1=1
|where dms_updated_at::date=$date_param```


Any advice is appreciated, love this project!

1 个答案:

答案 0 :(得分:1)

根据您的用例,听起来您对这个较旧问题的功能感兴趣: https://github.com/fishtown-analytics/dbt/issues/1096。由于社区缺乏兴趣,我们于5月关闭了该问题,但这并不意味着人们今天没有遇到此问题(以及有关该问题的详尽答案)。

如我所见,最好的答案是在模型底部包含一个宏{{ footer_sql() }},然后可以动态地(或不包括)您的环境特定逻辑:

{% macro footer_sql(date_param) %}

{% if target.name == 'ci' %}
where {{ date_param }} between dbt_valid_to and dbt_valid_from

{% elif target.name == 'prod' %}
where 1=1

{% elif target.name == 'dev' %}
where dms_updated_at::date= {{ date_param }}

{% endif %}

{% endmacro %}

最后但并非最不重要的一点,我只想解决您提到的一些问题:

不幸的是,似乎不支持调用宏。

您可以在set_sql_header调用中绝对包含Jinja宏,只要这些宏可以编译为SQL。这就是有多少用户在BigQuery上创建UDF。

此外,临时设置不受此设置的影响。

是的。 SQL标头的目的是在DDL create view as / create table as之前插入SQL;由于临时模型并未实现为数据库对象,因此它们之前没有DDL。