从 DBT 宏创建模型

ski*_*bee 2 dbt

我想创建多个dbt模型(具体化为views)我有一个macro基于各种参数创建 sql 语句的模型。

我当前的策略是在 中创建 SQL 语句列表,然后尝试从 中 macros/query_tables.sql调用.macromodels/mat_tables.sql

运行dbt buildtargetSQL 为空。

create or replace view mat_tables
  
   as (    

  );

Run Code Online (Sandbox Code Playgroud)

对于运行这样的过程有什么建议吗?

macros/query_tables.sql

{% macro query_tables() %} 
{% set query_list = [] %}
    {% set tables = ['MEDIA_LOADED ', 'MEDIA_DOWNLOADED', 'MEDIA_PLAYED'] %}
    
    {% for table_name in tables %} 
        {% set query %}   
            with events_{{table_name)}} as (
                select
                    user_id,
                    session_id,
                    {{ dbt_date.from_unixtimestamp("created_at", format="seconds") }}  as session_dt,
                    count(*) as cnt_{{table_name}}
                from
                    {{ table_name }}
                where
                    {{ dbt_date.from_unixtimestamp("created_at", format="seconds") }}  > '{{ var("start_date") }}'
                group by
                    1,2,3
            )
            select
                *
            from
                events_{{table_name}} 
        {% endset %}

        {% set query_list = query_list.append(query) %}
        {{ log(query, info=True) }}

    {% endfor %} 
    {{ return(query_list) }}
{% endmacro %}

Run Code Online (Sandbox Code Playgroud)

models/mat_tables.sql 运行该进程的代码是

{{ config(materialized='view') }}

{% set event_tables_query= query_event_tables() %}

{% for table_query_tmp in event_tables_query %}
        {% do run_query(table_query_tmp) %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

tco*_*eer 5

dbt 模型确实需要与 RDBMS 中的物化资产进行 1:1 映射。换句话说,您想要创建的每个视图都需要一个模型文件。

run_query将在数据库中执行查询,在本例中只是一条 select 语句。来自该 select 语句的数据可以使用 返回到 jinja 上下文{% set data = run_query(table_query_tmp) %},但是您的do语句不会将该数据保留在任何地方(在这种情况下,这是错误的方法 -run_query实际上是将少量数据返回到 jinja 上下文动态生成sql的目的)。

换句话说,你可以大大简化你的宏:

-- macros/get_media_query.sql

{% macro get_media_query(table_name) %}
with
    events_{{ table_name) }} as (
        select
            user_id,
            session_id,
            {{ dbt_date.from_unixtimestamp("created_at", format="seconds") }}
            as session_dt,
            count(*) as cnt_{{ table_name }}
        from {{ table_name }}
        where
            {{ dbt_date.from_unixtimestamp("created_at", format="seconds") }}
            > '{{ var("start_date") }}'
        group by 1, 2, 3
    )
select *
from events_{{ table_name }}
{% endmacro %}
Run Code Online (Sandbox Code Playgroud)

然后创建 3 个模型文件,使用正确的表名称调用宏:

-- models/media_loaded.sql
{{ config(materialized='view') }}
{{ get_media_query('MEDIA_LOADED') }}


-- models/media_downloaded.sql
{{ config(materialized='view') }}
{{ get_media_query('MEDIA_DOWNLOADED') }}


-- models/media_played.sql
{{ config(materialized='view') }}
{{ get_media_query('MEDIA_PLAYED') }}
Run Code Online (Sandbox Code Playgroud)