## What — pre-hook を使うべきではない理由 要するに、処理が `.sql` と `.yml` の2箇所に散るのが問題。重複排除のような前処理は、そのモデルのSQLファイルの中に置いた方が読める。 - **デバッグが困難**: エラーが発生した際に原因の特定が難しい - **予期しない副作用**: 実行タイミングが分かりにくく、予期しない動作を引き起こす可能性 - **テストが困難**: pre-hookの動作をテストするのが難しい - **可読性の低下**: SQLファイルを見ただけでは、pre-hookの存在に気づけない なお `source`(sources.yml)にはそもそも `pre-hook` を定義できない。 ## How — 代替3手 重複排除は QUALIFY句と ROW_NUMBER() を使うのがいちばん短い(BigQueryの場合)。処理を切り離したいときは方法3の中間モデルにする。 **方法1: QUALIFY句とROW_NUMBER()を使用(推奨)** ```sql -- sample_model.sql SELECT * FROM {{ source('raw_data', 'raw_data') }} QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY _load_ts DESC) = 1 ``` **方法2: CTEとウィンドウ関数を使用** ```sql WITH ranked_data AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY _load_ts DESC) AS rn FROM {{ source('raw_data', 'raw_data') }} ) SELECT * FROM ranked_data WHERE rn = 1 ``` **方法3: 中間モデルを作成して処理を分離** ```sql -- staging/raw_data_deduplicated.sql SELECT * FROM {{ source('raw_data', 'raw_data') }} QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY _load_ts DESC) = 1 ``` ```sql -- staging/sample_model.sql SELECT * FROM {{ ref('raw_data_deduplicated') }} WHERE condition = 1 ``` > [!warning] もしpre-hookを使わざるを得ない場合 > 基本的には避けるべきだが、やむを得ない場合のみ。必ずコメントで理由を明記する・ドキュメントに記録する・チームメンバーと相談する。 ## 関連 - [[データ基盤]] - [[dbtのYAMLファイルの書き方手順]] — source と model の使い分け・基本構造 - [[BigQueryのウィンドウ関数]] — 方法1・2で使う `ROW_NUMBER()` の側