[小ネタ]dbt×Snowflakeでtarget.nameに応じてTransient Tableで作成するかどうかを切り替える方法
さがらです。
dbt×Snowflakeでtarget.nameに応じてTransient Tableで作成するかどうかを切り替える方法について、本記事でまとめます。
前提知識:Transient Tableについて
まず、dbt×Snowflakeにおいては、「デフォルトでTransient Tableでテーブルが作られる」という仕様があります。以下のリンク先のドキュメントにおいても、「 By default, all Snowflake tables created by dbt are transient.」と言及があります。
以下の表は公式Docsからの引用ですが、Transient Tableは「Time Travel Retention Periodを0か1にしか設定できない」、「Fail-safeが適用されない」という仕様となっています。

これは私の推測も含めますが、dbtは加工元のソースデータさえあれば定義したModelのコードですぐに加工後のテーブルが生成できるため、デフォルトはTransient Tableで作成するという仕様になっているのだと思います。
ただ、データ量が多くIncremental Modelでビルドをしているようなテーブルだとテーブルの再生成にかなりの時間がかかってしまい、ビジネスの根幹に関わるデータパイプラインだと修復までに時間がかかってしまうリスクがあります。そのため、「dbtで変換を行って生成したテーブルでもタイムトラベル機能で数日前の状態に戻したい」というケースはありえると思います。
このケースにおいて、「ビジネスに影響を及ぼさない開発環境ではTransient Tableで作成し、ビジネスに影響が及ぶ本番環境では通常のテーブルで作成したい」と考える方は多いと思い、本記事の内容の検証に至りました。
dbt×Snowflakeでtarget.nameに応じてTransient Tableで作成するかどうかを切り替える方法
早速結論ですが、dbt×Snowflakeでtarget.nameに応じてTransient Tableで作成するかどうかを切り替えるには、dbt_project.ymlにおいて以下のように+transientの設定をすればOKです。
version: 2
# 関連するmodelsだけを抜粋
models:
  jaffle_shop:
    +transient: "{{ false if target.name == 'prod' else true }}"
    staging:
      materialized: view
    marts:
      materialized: table
動作確認
上述のようにdbt_project.ymlを設定した上で、target.nameは下記のように設定して、動作確認を行ってみます。
- 開発環境の
target.name:dev - 本番環境の
target.name:prod 
※dbt Cloudでのtarget.nameの設定方法は下記ブログが参考になると思いますので、併せてご覧ください。
開発環境での確認
dbt Cloudでの開発環境に当たるIDE上でdbt buildコマンドを実行し、作られたテーブルの定義を確認してみます。
以下が開発環境のスキーマで作られたテーブルのDDL文ですが、開発環境ではTransient Tableとして作成されています。

本番環境での確認
dbt Cloudでの本番環境に当たる、Production Environment上でのジョブでtarget.nameをprodと設定し、そのジョブでdbt buildを実行し、作られたテーブルの定義を確認してみます。
以下が本番環境のスキーマで作られたテーブルのDDL文ですが、開発環境の時と異なりTRANSIENTの一文が抜けて、普通のテーブルとして作成されています。









