imu-note
いむたろ
いむたろ
@imutaroh
新卒エンジニア / データ基盤 × AI

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()を使用(推奨)

-- 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とウィンドウ関数を使用

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: 中間モデルを作成して処理を分離

-- 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
-- staging/sample_model.sql
SELECT *
FROM {{ ref('raw_data_deduplicated') }}
WHERE condition = 1
もしpre-hookを使わざるを得ない場合

基本的には避けるべきだが、やむを得ない場合のみ。必ずコメントで理由を明記する・ドキュメントに記録する・チームメンバーと相談する。

関連