Open3
【dbt】dbt snapshot
公式
delete処理:宛先テーブルに存在するレコードがソーステーブルでdeleteされていた場合
update処理:宛先テーブルと比較してソーステーブルのレコードがupdateされていた場合
insert処理:宛先テーブルに無いレコードがソーステーブル側に新規で作成されていた場合
細かく挙動が説明されていた
Slowly Changing Dimension の Type 0~7 が何を意味しているのかわかる
わかりやすい
{% snapshot daily_data_snapshot %}
{{
config(
target_database=[BigQueryで言うところのプロジェクト名]
target_schema=[データセット],
unique_key=[主キー],
strategy='timestamp',
updated_at=[date型のカラム。ここに指定した列を最終更新日時として、既存テーブルと比較して更新された行をINSERTする],
)
}}
select
*
from
{{ source([データセット名], [テーブル名]) }}
{% endsnapshot %}
snapshotに関するベストプラクティス
snapshotはとても便利な機能なのですが、使い方を誤ると、全く活用されない大量のデータを保持してしまうなど、リスクに繋がる可能性があります。
以下は公式Docからの引用ですが、snapshotに関するベストプラクティスを、私なりに解釈してまとめておきます。
-
Strategyはできる限り「timestamp」を使用する
- 差分を効率的に検知し、最適なデータ更新を行うためです。
-
unique_key
が本当にユニークであることを確認する-
unique_key
はスナップショットを正確に機能させるために重要です。unique_key
の一意性を保証するためにschema testを設定することも推奨されます。
-
-
Snapshot用に別のスキーマを定義する
- 分析用データとスナップショットを別スキーマにすることで、意図しない削除からデータを保護できます。Snowflakeなどでは、スナップショット生成時に別のロールを使用して削除を防ぐといった運用も可能です。
-
Sourceに対してSnapshotを行う
- クレンジング処理を行う前の生データをスナップショットすることが理想です。元データをそのまま保存することで、将来のデータ追跡に役立ちます。
-
Sourceを参照する際は
source
関数を使う-
source
関数を使うことで、データリネージが追跡可能になり、データの出所を明確にすることができます。
-
-
Snapshotには、できるだけ多くのカラムを選択する
- 可能であれば
select *
を使用し、将来的に利用する可能性があるカラムをすべてスナップショットするのが理想です。
- 可能であれば
-
SnapshotのSELECT文でJOINを避ける
- JOINを含むクエリは、timestampの信頼性を損なう可能性があります。JOINが必要な場合は、各元テーブルごとにスナップショットを取ることを検討してください。
-
SnapshotのSELECT文でデータのクレンジングやロジックの実装を避ける
- クレンジング処理やロジックは将来的に変更が必要になる可能性があるため、シンプルなクエリでスナップショットを取ることが推奨されます。ただし、JSONのカラムを展開する場合などは例外です。
これらのポイントを守ることで、スナップショットの効果的な活用とデータの管理がスムーズになります。
--store-failures フラグ
dbt test を実行したときに失敗したテストによって条件を満たさなかった行を保存する事が出来ます。
それが --store-failures フラグです。
dbt test --select ./models/sources --store-failures
ソースのみでテストを実行する
$ dbt test --select source:jaffle_shop