1

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

除了注释块之外,是否可以合理地调整 query_header代码以支持注入原始 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!

4

1 回答 1

1

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

正如我所看到的,最好的答案是{{ 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 标头的目的是插入将在create view as/ create table asDDL 之前的 SQL;由于临时模型没有具体化为数据库对象,因此它们之前没有 DDL。

于 2020-07-21T14:31:12.693 回答