◾️はじめに
https://dk521123.hatenablog.com/entry/2023/12/04/000000
の続き。 dbt の materialized='incremental'で、 個人的に少し学びがあったので、メモしておく
目次
【1】やりたいこと 補足:DELETE+INSERTに関して 【2】サンプル 補足:実際には何を行なっているのか? 【3】Tips 1)load_relation 2)COALESCE
【1】やりたいこと
materialized='incremental' で基本、洗い替えなのだが 各カラムデータでデータがなかった場合、更新前データで補完したい。 => materialized='incremental' は、DROP&CREATE TABLEで 更新前データが既になくなると思っていたが、 WITHで呼び出しておけば使えた => 呼び出す前に「load_relation(this)」を使ったり 少しTips的なことがある(以下のサンプル参照)
補足:DELETE+INSERTに関して
* DELETE+INSERTに関しても、同様な感じで実装できる。 => 違いがあるとすれば、 load_relationではなく、is_incremental()を使う
dbt ~ 更新 / Delete and Insert ~ https://dk521123.hatenablog.com/entry/2023/12/20/000104
【2】サンプル
* データ自体は、以下の関連記事で扱ったものをベースに作成
https://dk521123.hatenablog.com/entry/2025/09/03/093606
[実行手順] [1] dbt seed 実行 [2] dbt run 実行(dbt run --log-level DEBUG) [3] seeds配下のCSVを修正 [4] dbt seed 実行 [5] dbt run 実行(dbt run --log-level DEBUG)
models/demo/user_full.sql
{{
config(
materialized='table'
)
}}
WITH
FULL_TABLE AS (
{% set relation_exists = load_relation(this) is not none %}
{% if relation_exists %}
SELECT * FROM {{ this }}
{% else %}
SELECT
NULL AS user_id,
NULL AS name,
NULL AS gender,
NULL AS email,
NULL AS remarks
{% endif %}
),
USER_TABLE AS (
SELECT * FROM {{ ref('user') }}
),
USER_PII AS (
SELECT * FROM {{ ref('user_pii') }}
),
FINAL_TABLE AS (
SELECT
COALESCE(u.user_id, pi.user_id) AS user_id,
COALESCE(pi.name, f.name) AS name,
COALESCE(u.gender, f.gender) AS gender,
COALESCE(pi.email, f.email) AS email,
COALESCE(u.remarks, f.remarks) AS remarks
FROM
USER_TABLE AS u
FULL OUTER JOIN
USER_PII AS pi
ON
u.user_id = pi.user_id
LEFT OUTER JOIN
FULL_TABLE AS f
ON
u.user_id = f.user_id
OR pi.user_id = f.user_id
)
SELECT * FROM FINAL_TABLE
seeds/user.csv
user_id,name,email 00001,Mike,demo1@sample.com 00004,Naomi,demo4@sample.com 00005,Smith,demo5@sample.com 11001,Ken,demo6@sample.com 11005,Kevin,demo7@sample.com
seeds/user_pii.csv
user_id,gender,remarks 00001,male,Hello 00003,male, 11001,male,!! 11002,female,World
dbt_project.yml
name: 'my_project' version: '1.0.0' # ... # "user_id: text"しないとIntになる seeds: my_project: user: +column_types: user_id: text user_pii: +column_types: user_id: text
補足:実際には何を行なっているのか?
https://dk521123.hatenablog.com/entry/2023/12/04/000000
より抜粋
1)処理フロー・概要
Step1: TMPテーブル(user_full__dbt_tmp)で作る Step2: 元テーブル(user_full)を バックアップ(user_full__dbt_backup)としてリネームする Step3: TMPテーブル(user_full__dbt_tmp)を 対象テーブル(user_full)としてリネームする Step4: コミット Step5: バックアップ(user_full__dbt_backup)をDrop
【3】Tips
1)load_relation
* 以下の関連記事を参照のこと
dbt Macro ~ load_relation ~
https://dk521123.hatenablog.com/entry/2025/09/02/000214
2)COALESCE
* 与えられた引数から NULLでない最初の引数を返却する * cf. coalesce(コーレス) = 合体する、融合する
構文
-- 引数 v1, v2, ... のうち、NULLでない最初の引数を返却する COALESCE(T v1, T v2, ...)
関連記事
dbt ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2023/06/30/000000
dbt ~ 環境設定 / Docker 編 ~
https://dk521123.hatenablog.com/entry/2024/10/11/230419
dbt ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/05/30/151003
dbt ~ 基本編 / Source ~
https://dk521123.hatenablog.com/entry/2023/12/08/111012
dbt ~ 更新 / 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2023/12/07/060129
dbt ~ 更新 / Update or Insert / Insert ~
https://dk521123.hatenablog.com/entry/2023/12/19/224453
dbt ~ 更新 / Delete and Insert ~
https://dk521123.hatenablog.com/entry/2023/12/20/000104
dbt ~ 更新 / DROP + CTAS ~
https://dk521123.hatenablog.com/entry/2023/12/04/000000
dbt 〜 生成されるSQL文を確認する 〜
https://dk521123.hatenablog.com/entry/2024/08/25/002741
dbt Macro ~ load_relation ~
https://dk521123.hatenablog.com/entry/2025/09/02/000214
テーブルの結合 ~ 完全外部結合・FULL JOIN ~
https://dk521123.hatenablog.com/entry/2025/09/03/093606