使用 dbt,如何在 jinja 表达式的宏调用中使用模型 cte?

问题描述 投票:0回答:2

我如何在 jinja 表达式块内的宏调用中引用先前定义的 cte?

with stg_example_table as (

  select *
  from {{ ref('stg_db__example_table') }}
  where {{ ref('stg_db__example_table') }}.example_column = 'foobar'

),

earliest_date as (
                                                   THIS
  {{                                         vvvvvvvvvvvvvvvvv
    get_earliest_date('month', 'created_at', stg_example_table)
  }}                                         ^^^^^^^^^^^^^^^^^
  
)

select * from earliest_date

我似乎无法以有效的方式引用该位置的 cte、stg_example_table。应该如何以有效的方式引用它?

如果我使用

ref('stg_db__example_table')
,宏 get_earliest_date() 就可以工作。但后来我得到了错误的值,因为表格没有像 cte 那样缩小。

我可以创建另一个 stg 模型,其中包含我需要的过滤器和 ref() 那个模型,但最好在这里使用 cte。

我也尝试过各种形式:

{% set earliest_date = run_query("select min(created_at)::date from stg_db__example_table").columns[0][0] %}

然后引用设置的earest_date,但我无法让它工作。

作为参考,这是 get_earliest_date() 宏:

{% macro get_earliest_date(date_component, column_name, relation) %}

{% set query %}
  select
    date_trunc({{ date_component }}, min({{ column_name }}))::date as earliest
  from {{ relation }}
{% endset %}

{% set results = run_query(query) %}


{% if execute %}

{% set result = results.columns[0][0] %}

{% else %}
{% set result = null %}

{% endif %}

{{ return(result) }}

{% endmacro %}

示例代码已简化,但最终我想得到一个 date_spine() :

  {{ 
    dbt_utils.date_spine(
      datepart = "month",
      start_date = get_earliest_date('month', 'created_at', stg_example_table),
      end_date = "date_trunc('month', current_date())"
    )
  }}
sql jinja2 dbt
2个回答
0
投票

dbt 不会解析您的模型,因此它根本不知道

stg_example_table
是什么。

如果您希望重复使用 CTE,它可能应该是它自己的模型(宏是另一种选择)。您可以使用

ephemeral
物化,并且 dbt 不会将任何内容保留到您的仓库中——它只是将模型插入为 CTE。对于如何
ref
临时模型有一些限制,但我认为在这种情况下,由于您从模型中调用
get_earliest_date
,它应该可以正常工作。

-- in stg_example_table.sql
{{ config(materialized="ephemeral") }}
select *
from {{ ref('stg_db__example_table') }}
where {{ ref('stg_db__example_table') }}.example_column = 'foobar'

-- in your_model.sql
...
{{ 
    dbt_utils.date_spine(
      datepart = "month",
      start_date = get_earliest_date('month', 'created_at', ref('stg_example_table')),
      end_date = "date_trunc('month', current_date())"
    )
}}

-1
投票

感谢您部分解决了我的问题。但是,我不喜欢使用多个文件,因为我的项目必须遵循特定的结构。是否可以将宏代码直接作为 SQL 嵌入到包含公共表表达式的模型中?

© www.soinside.com 2019 - 2024. All rights reserved.