dbtのtagについて細かな挙動を確認してみた #dbt

2022.07.01

さがらです。

dbtにはtagという機能があり、model、snapshot、seed、testなどにtagを付与することで、各種dbtコマンド実行時に指定したtagが付いているものだけを実行対象とすることができます。

tag自体はシンプルな機能なのですが、色々と条件が重なったときにどういった挙動をするのか気になったため確かめてみました。その内容を本記事でまとめてみます。

複数tagを指定する方法

検証時のコード

  • aaa.sql
{{ config(
    tags=["aaa","odd"]
) }}

select * from {{ source('jaffle_shop','orders') }}
  • bbb.sql
{{ config(
    tags=["bbb","even"]
) }}

select * from {{ ref('aaa') }}
  • ccc.sql
{{ config(
    tags=["ccc","odd"]
) }}

select * from {{ ref('bbb') }}
  • リネージ

OR条件で複数のtagを指定する方法

OR条件で複数のtagを指定する時は、tag:同士をスペースで区切ればOKです。

AND条件で複数のtagを指定する方法

AND条件で複数のtagを指定する時は、tag:同士をカンマで区切ればOKです。

検証時の気づき

最初はtag:1つだけで複数tagの設定が出来ると思ったのですが、以下の現象に遭遇したため、tag:は複数回記述するほうが良さそう、という結論に至っています。

  • dbt run --select tag:odd,aaa:aaa.sqlが実行される

  • dbt run --select tag:aaa,odd:何も実行されない

参考Doc

あるmodelにtagが複数付与されているとき、selectとexcludeそれぞれで付与されているtagを選択するとどうなるか

検証時のコード

  • aaa.sql
{{ config(
    tags=["aaa","odd"]
) }}

select * from {{ source('jaffle_shop','orders') }}

検証結果

記述する順番に関係なく、--excludeで指定したtagを除外する処理を優先するようです。

別リポジトリをpackageとしてインストールしたときにtagを指定して、合致するmodelだけ実行されるか

検証時のコード

  • stg_customers.sql ※packageとしてインストールしたリポジトリ上に存在
{{ config(
    tags=["staging","customer"]
) }}

select
    id as customer_id,
    first_name,
    last_name

from {{ source('jaffle_shop','customers') }}
  • stg_orders.sql ※packageとしてインストールしたリポジトリ上に存在
{{ config(
    tags=["staging","order"]
) }}

select
    id as order_id,
    user_id as customer_id,
    order_date,
    status,
    _etl_loaded_at

from {{ source('jaffle_shop','orders') }}
  • customers.sql
{{ config(
    tags=["mart","customer"]
) }}

with customers as (

    select * from {{ ref('stg_customers') }}

),

orders as (

    select * from {{ ref('stg_orders') }}

),

customer_orders as (

    select
        customer_id,

        min(order_date) as first_order_date,
        max(order_date) as most_recent_order_date,
        count(order_id) as number_of_orders

    from orders

    group by 1

),


final as (

    select
        customers.customer_id,
        customers.first_name,
        customers.last_name,
        customer_orders.first_order_date,
        customer_orders.most_recent_order_date,
        coalesce(customer_orders.number_of_orders, 0) as number_of_orders

    from customers

    left join customer_orders using (customer_id)

)

select * from final
  • リネージ

  • packageインストール後のリポジトリのフォルダ構成

検証結果

インストールしたリポジトリでも使用されているtagであるcustomerを指定して実行すると、問題なく関連するmodelだけが実行できました。

最後に

tagの挙動を色んな条件で確かめてみました。

今回の検証で調べているときに、tagの条件が複雑な場合はSelectorsというものが使えそうということもわかったので、これもいつか検証したいですね。