【dbt】dbt Macro ~ 基本編 ~

■ はじめに

https://dk521123.hatenablog.com/entry/2023/11/29/003751

の続き。

DBT の Macro 作ったので、実用的な例をメモしておく

目次

【1】macro の引数
 1)デフォルト引数
【2】例外
 1)例外をスローする
【3】コメント文
【4】デバッグログ機能
 1)print()文
 2)log()関数
【5】サンプル
 例1:PostgreSQL/Snowflake での UTC時間取得
 例2:クリーン処理

【1】macro の引数

* 以下が参考になる

https://zenn.dev/mashiike/articles/79fd09a3a1a7cc
https://zenn.dev/mashiike/books/f51a51997c2f0e/viewer/816fa9

1)デフォルト引数

{%- macro demo_func(msg1='hello', msg2='world') %}
-- {{ msg1 }} {{ msg2 }}
{%- endmacro %}

【2】例外

1)例外をスローする

* exceptions.raise_compiler_error() でスローできる

https://docs.getdbt.com/reference/dbt-jinja-functions/exceptions

{% if number < 0 or number > 100 %}
  {{ exceptions.raise_compiler_error("Invalid `number`. Got: " ~ number) }}
{% endif %}

【3】コメント文

* dbt というよりJinja2

Jinja2 ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2024/10/18/001757

{# コメント文 #}

{#
コメント文1
コメント文2
#}

https://tekunabe.hatenablog.jp/entry/2021/12/03/jinja2_comment

【4】デバッグログ機能

1)print()文

* ログとして、print()文が用意されている

macros/demo_macro.sql

{% macro demo_macro(user_id) -%}
  {{ print(user_id) }}
{%- endmacro %}

コマンド例

# Suppress all non-error logging to stdout.
# Does not affect {{ print() }} macro calls.
$ dbt run-operation demo_macro --args '{user_id: X001}' --quiet
X001

2)log()関数

* ログ

https://docs.getdbt.com/reference/dbt-jinja-functions/log
構文

-- msg:メッセージ
-- info:False:ログファイルだけ。
-- True:ログファイルと標準出力 (default=False)
def log(msg: str, info: bool = False) -> str: 

サンプル

{% macro some_macro(arg1, arg2) %}
  {{ log("Running some_macro: " ~ arg1 ~ ", " ~ arg2) }}
  -- ~(チルダ):文字列連結(Pythonの「+」)

  {{ log("Hello"), True) }}
  {{ log("World", info=True) }}
{% endmacro %}

【5】サンプル

例1:PostgreSQL/Snowflake での UTC時間取得

-- 呼び出し側
SELECT
 {{ utc_current_timestamp('YYYY-MM-DD') }} AS current_date
FROM
 demo_table;

macros/utc_current_timestamp.sql

{% macro utc_current_timestamp(datetime_format) -%}
    {{ return(adapter.dispatch('utc_current_timestamp')(datetime_format)) }}
{%- endmacro %}

-- For PostgreSQL
{% macro postgres__utc_current_timestamp(datetime_format) %}
    to_char(current_timestamp at time zone 'UTC', datetime_format)
{% endmacro %}

-- For Snowflake
{% macro snowflake__utc_current_timestamp(datetime_format) %}
    TO_VARCHAR(sysdate(), datetime_format)
{% endmacro %}

例2:クリーン処理

-- 呼び出し側
SELECT
 {{ clean('id') }} AS id,
 {{ clean('name') }} AS name,
 {{ clean('age') }} AS age
FROM
 demo_table;

macros/clean.sql

{% macro clean(target_item) -%}
  CASE WHEN UPPER(TRIM({{ target_item }})) IN ('','\"\"','N/A','NULL') THEN NULL ELSE TRIM({{ target_item }}) END
{%- endmacro %}

関連記事

dbt ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2023/06/30/000000
dbt ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/05/30/151003
dbt ~ 条件分岐 ~
https://dk521123.hatenablog.com/entry/2024/09/11/003301
dbt ~ SQL実行関数 / run_query ~
https://dk521123.hatenablog.com/entry/2025/04/28/000032
dbt Macro ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/11/29/003751
dbt Macro ~ DWHごとに処理切替 / adapter.dispach ~
https://dk521123.hatenablog.com/entry/2024/08/20/150724
Jinja2 ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2024/10/18/001757
Jinja2 ~ Macro ~
https://dk521123.hatenablog.com/entry/2023/11/28/235951