我试图在 dbt 模型中设置一个变量。
但是,我正在努力克服遇到的问题。根据我的理解,dbt_utils.get_column_values() 不适用于 CTE,但是为了克服这个问题,我构建了一个辅助模型来模拟 cte 并构建一个表。
从这个表中(参见下面的打印截图),我想获取字符串之间的最大级别,级别将由 / 分割
为此我构建了这个模型:
--/models/dim_product/stg/stg_aux_calculate.sql
select max(LENGTH(VALUE) - LENGTH(REPLACE(VALUE, '/', '')))::integer as max_splits
from {{ source('schema', 'category_tbl') }}
这将生成此表(使用雪花):
从这里我创建一个新模型,想要选择值 5 将其设置为变量
-- will need to add 1 to account for the original string (tackle after)
--/models/dim_product/stg/stg_category_model.sql
{%- set max_splits = dbt_utils.get_column_values(
table = ref('stg_aux_calculate'),
column = 'max_splits')[0] -%}
with split_values as (
select
value_id,
value,
{% for i in range(1, max_splits) %}
split_part(value, '/', {{ i }}) as value_component_{{ i }},
{% endfor %}
ATTRIBUTE_ID,
ENTITY_ID,
STORE_ID
from {{ source('schema', 'category_tbl') }}
)
select
value_id,
value,
{% for i in range(1, max_splits) %}
max(value_component_{{ i }}) as value_component_{{ i }}{% if not loop.last %},{% endif %}
{% endfor %}
,
ATTRIBUTE_ID,
ENTITY_ID,
STORE_ID
from split_values
group by value_id,value, ATTRIBUTE_ID, ENTITY_ID, STORE_ID
我得到的错误是
TypeError: 'Undefined' object cannot be interpreted as an integer
我知道这是可行的,因为如果我用以下方法对变量进行硬编码:
{% set max_splits = 6 %}
它将返回我所期望的:
在雪花上,stg_aux_calculate.sql 模型是这样创建的
create or replace view DEV_etc.DBT_my_name_xyz.stg_aux_calculate(
MAX_SPLITS
) as (
select max(LENGTH(VALUE) - LENGTH(REPLACE(VALUE, '/', '')))::integer as max_splits
from DEV_RAW_INT
.conf.CATALOG_CATEGORY_conf
);
有什么建议可以克服这个问题吗?
我已经做了一些玩具,工作示例。让我们看看:
-- my_splits_model.sql // this will just return an integer
select 5 as max_splits
-- my_downstream_model.sql
{%- set max_splits = dbt_utils.get_column_values(
table = ref('my_splits_model'),
column = 'max_splits'
)[0]
-%}
-- we want to make sure that the `max_splits` variable is an actual number
{% if max_splits is number %}
select
'{{ max_splits }}' as this_is_my_max_splits
{% for split in range(1, max_splits) %}
, 'split_number_{{ split }}' as split_{{ split }}
{% endfor %}
{% else %}
select 'hmmm' as that_is_not_a_number
{% endif %}
最后一个模型编译为:
select
'5' as this_is_my_max_splits
, 'split_number_1' as split_1
, 'split_number_2' as split_2
, 'split_number_3' as split_3
, 'split_number_4' as split_4
如果我更新
my_splits_model.sql
以返回非整数的内容:
-- my_splits_model.sql // this will now not return an integer
select 'some text' as max_splits
然后
my_downstream_model
将编译为:
select 'hmmm' as that_is_not_a_number
因此,对于您的用例:我只是通过使用 Jinja 的内置测试
is number
确保您实际从 max_splits
set
获得的是一个实际数字。