我有一组 35 个模型,对应于我的暂存层中不同类型的对象,我将它们合并到中间层中。为了这篇文章的目的,我已将我正在使用的数据源替换为 xxx。为了执行联合,我使用以下 jinja
for
循环,该循环使用 ref
函数来引用这些表。
{% set object_types = dbt_utils.get_column_values(
table=ref("ref_include_object_types"),
column="object_type"
) %}
WITH base AS (
{%- for object_type in object_types %}
SELECT
'{{ object_type }}' AS object_type,
{{ object_type }} AS object_value
FROM {{ ref(object_type) }}
{%- if not loop.last %}
UNION
{%- endif %}
{% endfor %}
)
ref
调用来构建依赖关系图,上面的代码会导致编译错误,并建议我为所有对象类型添加 -- depends_on: {{ ref(object_type_name) }}
语句:
Compilation Error in model int_xxx__combine_object_instances (models\intermediate\xxx\int_xxx__combine_object_instances.sql)
dbt was unable to infer all dependencies for the model "int_xxx__combine_object_instances".
To fix this, add the following hint to the top of the model "int_xxx__combine_object_instances":
-- depends_on: {{ ref('stg_xxx__object_type_name') }}
我显然可以动态创建一个
-- depends_on:
语句列表来处理这个问题,但我宁愿避免这种情况,因为这会使代码更难以维护和阅读。
此问题的评论中建议了另一种解决方案:
{% for model in object_types %} {% set depends_on = "--depends_on: {{ ref( '" ~ model ~ "' ) }}" %} {{ depends_on }} {% endfor %}
这个解决方案对我不起作用,但我不确定为什么。我得到与以前完全相同的编译错误。该解决方案在 github 上得到了赞成和反对,但没有人真正评论过为什么它是一个好/坏的解决方案,或者为什么它可能不起作用。我认为它不起作用,因为依赖项再次位于 jinja 中,并且在编译期间不会呈现。
该问题是由调用
dbt_utils.get_column_values
函数引起的。
{% set object_types = dbt_utils.get_column_values(
table=ref("ref_include_object_types"),
column="object_type"
) %}
检查源代码可以找到以下几行:
{# Prevent querying of db in parsing mode. This works because this macro does not create any new refs. #}
{%- if not execute -%}
{% set default = [] if not default %}
{{ return(default) }}
{% endif %}
显然,该函数在编译期间没有被调用,因为他们不想在解析模式下查询数据库并创建更多引用。
我通过用项目变量替换种子表并创建用于解析它们的宏来解决这个问题。