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