こんちには。
データアナリティクス事業本部 インテグレーション部 機械学習チームの中村です。
今回は、dbtのベストプラクティスをより理解するために、dbt-athenaを使って新規プロジェクトからdbtのベストプラクティスに寄せてみたいと思います。
ベストプラクティスについて
ベストプラクティスの記載
ベストプラクティスの情報源としては以下を参考にします。
- 公式ドキュメント
また、これらを別途まとめてくださっている方の記事も以下にあります。
- まとめ記事
ベストプラクティスの私的まとめ
まとめ記事と重複してしまいますが、私が理解したベストプラクティスをまとめます。
ポイントを以下に列挙します。
- models配下は以下の3層構造
- staging、intermediate、marts
- stagingレイヤ
- 命名規則 :
stg_{source_name}__{table_name}.sql
{source_name}
毎にサブフォルダに分割- この層でやること : リネーム、キャスト、単位変換、カテゴリ変数のエンコード
- この層でやらないこと : join、aggregate(例外あり)
- materialized設定はview
- stagingレイヤはsourceを入力として使用する唯一の場所
- stagingレイヤのモデルはソーステーブルと1対1対応
- intermediate、martsはこのstagingレイヤのモデルを参照(ref)
- 命名規則 :
- intermediateレイヤ
- 命名規則 :
int_[entity]s_[verb]s.sql
- materialized設定はephemerally(WITH句)
- 厳密な名づけルールは困難だが、intermediateレイヤの動詞で考えるのが良い指針(pivoted、joinedなど)
- intermediateレイヤはエンドユーザ(ダッシュボードやアプリなど)に非公開
- intermediateレイヤの目的はmartsレイヤの複雑さの解消
- そのため早い段階では不使用を推奨(martsレイヤのモデルが10個未満など)
- サブディレクトリも早い段階では不使用を推奨
- 命名規則 :
- martsレイヤ
- 命名規則 : ルールは存在せず、実際に示すテーブル名通り
- materialized設定はtableまたはincremental
- intermediateレイヤ同様、早い段階ではサブフォルダ分割等は不使用を推奨
- ymlファイル
- schema.yml一つに書くのではなくmodelsとsourcesに分割するのが良い
- 命名規則 :
_[directory]__models.yml
、_[directory]__sources.yml
- doc(markdown)ファイル
- ymlファイルのdescriptionより豊富なドキュメントを記載することが可能
- 命名規則 :
_[directory]__doc.md
- 詳細は About documentation | dbt Developer Hub を参照
- materializedなどの設定
- 通常は
dbt_project.yml
などに各フォルダで共通の設定を記載することを推奨
- 通常は
- selectはタグ指定よりもフォルダ指定の方がベター
dbt run --select tag:marketing
よりもdbt run --select marts.marketing
- タグ指定は仕様の暗黙的な理解が必要で、フォルダ指定よりもタグの付け忘れが多くなることが理由
フォルダ・ファイル構成例
これらのベストプラクティスに基づくフォルダ・ファイルの構成例として示されているのが以下です。
jaffle_shop
├── README.md
├── analyses
├── seeds
│ └── employees.csv
├── dbt_project.yml
├── macros
│ └── cents_to_dollars.sql
├── models
│ ├── intermediate
│ │ └── finance
│ │ ├── _int_finance__models.yml
│ │ └── int_payments_pivoted_to_orders.sql
│ ├── marts
│ │ ├── finance
│ │ │ ├── _finance__models.yml
│ │ │ ├── orders.sql
│ │ │ └── payments.sql
│ │ └── marketing
│ │ ├── _marketing__models.yml
│ │ └── customers.sql
│ ├── staging
│ │ ├── jaffle_shop
│ │ │ ├── _jaffle_shop__docs.md
│ │ │ ├── _jaffle_shop__models.yml
│ │ │ ├── _jaffle_shop__sources.yml
│ │ │ ├── base
│ │ │ │ ├── base_jaffle_shop__customers.sql
│ │ │ │ └── base_jaffle_shop__deleted_customers.sql
│ │ │ ├── stg_jaffle_shop__customers.sql
│ │ │ └── stg_jaffle_shop__orders.sql
│ │ └── stripe
│ │ ├── _stripe__models.yml
│ │ ├── _stripe__sources.yml
│ │ └── stg_stripe__payments.sql
│ └── utilities
│ └── all_dates.sql
├── packages.yml
├── snapshots
└── tests
└── assert_positive_value_for_total_amount.sql
構成例に基づいたGitHubのPublic Template
実際この構成例通りのレポジトリは見つけられなかったのですが、dbt-labsが公開しているものの中では以下のPublic Templateが最も近いように見えました。
今回は、新規プロジェクトをdbt-athenaで作成し、こちらの例を参考にしながらベストプラクティスに近づけていく作業をやりたいと思います。
やってみた
dbt実行環境の準備
まずはdbtの実行環境を構築します。
pyenv + poetryでPython環境を構築している前提で記載します。ご自身の環境に合わせて適宜読み返されてください。
# Pythonバージョンの設定
pyenv local 3.11.5
# poetryの初期化
poetry init
# dbtのモジュールをインストール
poetry add "dbt-core>=1.6.0,<1.7.0" dbt-athena-community
# バージョン確認
poetry export | grep "dbt" | awk '{print $1}'
# dbt-athena-community==1.6.4
# dbt-core==1.6.7
# dbt-extractor==0.4.1
# dbt-semantic-interfaces==0.2.3
# poetry環境へ入る
poetry shell
# dbtコマンド側でもバージョン確認
dbt --version
# Core:
# - installed: 1.6.7
# - latest: 1.7.0 - Update available!
#
# Your version of dbt-core is out of date!
# You can find instructions for upgrading here:
# https://docs.getdbt.com/docs/installation
#
# Plugins:
# - athena: 1.6.4 - Ahead of latest version!
こちらで一通り実行環境の構築が可能です。
dbtプロジェクト作成
最初からdbt init
で対話的にプロジェクトを作成しても良いのですが、結局のところ前回のブログでもお示した通りseed_s3_upload_args
の設定がうまくできないので、最初に~/.dbt/profiles.yml
に以下を記載しておきます。
jaffle_shop:
outputs:
dev:
database: awsdatacatalog
region_name: ap-northeast-1
s3_data_dir: s3://{ご自身のバケット名}/dbt/athena_query_result
s3_staging_dir: s3://{ご自身のバケット名}/dbt/tables
schema: jaffle_shop
seed_s3_upload_args: {}
threads: 1
type: athena
target: dev
なお{ご自身のバケット名}
の部分は適宜置き換えをお願いします。
ここでschema: jaffle_shop
はデフォルトスキーマと呼ばれ、この名前が出力先のAthenaにおけるデフォルトのデータベース名となります。
データ自体もこのデフォルトスキーマに応じたS3のパスに保存され、今回の場合は以下がデフォルトの格納先となります。
s3://{ご自身のバケット名}/dbt/tables/jaffle_shop
そして以下のようにdbt init
を実行するとprofiles.yml
を上書きしますか?とコンソールに聞かれるため、Noを選択してプロジェクトを作成します。
dbt init jaffle_shop
# 03:07:07 Running with dbt=1.6.7
# 03:07:07
# Your new dbt project "jaffle_shop" was created!
#
# For more information on how to configure the profiles.yml file,
# please consult the dbt documentation here:
#
# https://docs.getdbt.com/docs/configure-your-profile
#
# One more thing:
#
# Need help? Don't hesitate to reach out to us via GitHub issues or on Slack:
#
# https://community.getdbt.com/
#
# Happy modeling!
#
# 03:07:07 Setting up your profile.
# The profile jaffle_shop already exists in {profile.ymlのフルパス}. Continue and overwrite it? [y/N]: n
するとプロジェクトフォルダが作成されるため、その中に移動します。そこで接続設定の検証を行うためdbt debug
を実行します。
(私は実際にはdbt debug
をaws-vault
経由で行っています。ご自身の環境に応じてAWSプロファイルを有効にして実行されてください。)
# プロジェクトフォルダへ移動
cd ./jaffle_shop
# 接続設定の検証
dbt debug
# 03:00:20 Running with dbt=1.6.7
# 03:00:20 dbt version: 1.6.7
# 03:00:20 python version: 3.11.5
# 03:00:20 python path: {Pythonの実行ファイルのフルパス}
# 03:00:20 os info: Windows-10-10.0.19045-SP0
# 03:00:20 Using profiles dir at {profile.yml格納先フォルダ}
# 03:00:20 Using profiles.yml file at {profile.ymlのフルパス}
# 03:00:20 Using dbt_project.yml file at {dbt_project.ymlのフルパス}
# 03:00:20 adapter type: athena
# 03:00:20 adapter version: 1.6.4
# 03:00:20 Configuration:
# 03:00:20 profiles.yml file [OK found and valid]
# 03:00:20 dbt_project.yml file [OK found and valid]
# 03:00:20 Required dependencies:
# 03:00:20 - git [OK found]
#
# 03:00:20 Connection:
# 03:00:20 s3_staging_dir: s3://{ご自身のバケット名}/dbt/athena_query_result
# 03:00:20 work_group: None
# 03:00:20 region_name: ap-northeast-1
# 03:00:20 database: awsdatacatalog
# 03:00:20 schema: jaffle_shop
# 03:00:20 poll_interval: 1.0
# 03:00:20 aws_profile_name: None
# 03:00:20 aws_access_key_id: None
# 03:00:20 aws_secret_access_key: None
# 03:00:20 aws_session_token: None
# 03:00:20 endpoint_url: None
# 03:00:20 s3_data_dir: s3://{ご自身のバケット名}/dbt/tables
# 03:00:20 s3_data_naming: schema_table_unique
# 03:00:20 s3_tmp_table_dir: None
# 03:00:20 debug_query_state: False
# 03:00:20 seed_s3_upload_args: None
# 03:00:20 lf_tags_database: None
# 03:00:20 Registered adapter: athena=1.6.4
# 03:00:23 Connection test: [OK connection ok]
#
# 03:00:23 All checks passed!
上記のように問題ないことを確認できました。
以降はdbtプロジェクトフォルダ内で作業していきます。
dbt seedでソーステーブルを作成
dbt seed
を使うことでcsvファイルからテーブルを作成することが可能です。
ファイルの追加
Public Templateの以下にcsvファイルが格納されています。
こちらから以下のファイルをseeds
フォルダに配置します。
raw_customers.csv
raw_items.csv
raw_orders.csv
raw_products.csv
raw_stores.csv
raw_supplies.csv
dbt seedの実行
その後、dbt seed
を実行します。
dbt seed
# 03:25:17 Running with dbt=1.6.7
# 03:25:17 Registered adapter: athena=1.6.4
# 03:25:17 Found 2 models, 6 seeds, 4 tests, 0 sources, 0 exposures, 0 metrics, 378 macros, 0 groups, 0 semantic models
# 03:25:17
# 03:25:22 Concurrency: 1 threads (target='dev')
# 03:25:22
# 03:25:22 1 of 6 START seed file jaffle_shop.raw_customers ............................... [RUN]
# 03:25:42 1 of 6 OK loaded seed file jaffle_shop.raw_customers ........................... [INSERT 939 in 19.32s]
# 03:25:42 2 of 6 START seed file jaffle_shop.raw_items ................................... [RUN]
# 03:26:03 2 of 6 OK loaded seed file jaffle_shop.raw_items ............................... [INSERT 95368 in 21.52s]
# 03:26:03 3 of 6 START seed file jaffle_shop.raw_orders .................................. [RUN]
# 03:26:32 3 of 6 OK loaded seed file jaffle_shop.raw_orders .............................. [INSERT 59652 in 28.66s]
# 03:26:32 4 of 6 START seed file jaffle_shop.raw_products ................................ [RUN]
# 03:26:50 4 of 6 OK loaded seed file jaffle_shop.raw_products ............................ [INSERT 10 in 17.91s]
# 03:26:50 5 of 6 START seed file jaffle_shop.raw_stores .................................. [RUN]
# 03:27:08 5 of 6 OK loaded seed file jaffle_shop.raw_stores .............................. [INSERT 5 in 18.19s]
# 03:27:08 6 of 6 START seed file jaffle_shop.raw_supplies ................................ [RUN]
# 03:27:27 6 of 6 OK loaded seed file jaffle_shop.raw_supplies ............................ [INSERT 65 in 18.83s]
# 03:27:27
# 03:27:27 Finished running 6 seeds in 0 hours 2 minutes and 9.38 seconds (129.38s).
# 03:27:27
# 03:27:27 Completed successfully
# 03:27:27
# 03:27:27 Done. PASS=6 WARN=0 ERROR=0 SKIP=0 TOTAL=6
profiles.yml
で設定したデフォルトスキーマ(データベース、S3パス)に、テーブルが作成されていることが分かります。
またGlueデータベースをあらかじめ作成していなくても、自動で作成されるため便利ですね。
カスタムスキーマを設定する
ソーステーブルをデフォルトスキーマに作成しましたが、通常ソーステーブルとdbtで作成するテーブルはデータベースを分けておきたいケースが考えられます。
それを考慮してか、Public Templateでは以下のようなmacros/generate_schema_name.sql
が追加されています。
{% macro generate_schema_name(custom_schema_name, node) %}
{% set default_schema = target.schema %}
{# seeds go in a global `raw` schema #}
{% if node.resource_type == 'seed' %}
{{ custom_schema_name | trim }}
{# non-specified schemas go to the default target schema #}
{% elif custom_schema_name is none %}
{{ default_schema }}
{# specified custom schema names go to the schema name prepended with the the default schema name in prod (as this is an example project we want the schemas clearly labeled) #}
{% elif target.name == 'prod' %}
{{ default_schema }}_{{ custom_schema_name | trim }}
{# specified custom schemas go to the default target schema for non-prod targets #}
{% else %}
{{ default_schema }}
{% endif %}
{% endmacro %}
こちらはカスタムスキーマを指定した際に実行されるマクロで、以下のようなロジックがマクロとして入っています。
node.resource_type == 'seed'
で、seedの時はカスタムスキーマをそのままスキーマ名(データベース名)を使用target.name == 'prod'
で、targetがprodの時のみデフォルトスキーマとカスタムスキーマの連結がスキーマ名(データベース名)を使用
そのため、dbt_project.yml
に以下を追記してseeds
のカスタムスキーマをjaffle_shop_raw
に設定します。
seeds:
jaffle_shop:
+schema: jaffle_shop_raw
dbt seedの再実行
dbt seedの再実行をしますが、その前に一旦jaffle_shop
というGlueデータベースを削除しておきます。
そして再度dbt seed
を実行します。
dbt seed
# 01:36:03 Running with dbt=1.6.7
# 01:36:03 Registered adapter: athena=1.6.4
# 01:36:03 Found 6 seeds, 12 models, 6 sources, 0 exposures, 0 metrics, 624 macros, 0 groups, 0 semantic models
# 01:36:03
# 01:36:08 Concurrency: 1 threads (target='dev')
# 01:36:08
# 01:36:08 1 of 6 START seed file jaffle_shop_raw.raw_customers ........................... [RUN]
# 01:36:32 1 of 6 OK loaded seed file jaffle_shop_raw.raw_customers ....................... [INSERT 939 in 24.43s]
# 01:36:32 2 of 6 START seed file jaffle_shop_raw.raw_items ............................... [RUN]
# 01:36:59 2 of 6 OK loaded seed file jaffle_shop_raw.raw_items ........................... [INSERT 95368 in 26.71s]
# 01:36:59 3 of 6 START seed file jaffle_shop_raw.raw_orders .............................. [RUN]
# 01:37:36 3 of 6 OK loaded seed file jaffle_shop_raw.raw_orders .......................... [INSERT 59652 in 36.87s]
# 01:37:36 4 of 6 START seed file jaffle_shop_raw.raw_products ............................ [RUN]
# 01:38:00 4 of 6 OK loaded seed file jaffle_shop_raw.raw_products ........................ [INSERT 10 in 23.70s]
# 01:38:00 5 of 6 START seed file jaffle_shop_raw.raw_stores .............................. [RUN]
# 01:38:24 5 of 6 OK loaded seed file jaffle_shop_raw.raw_stores .......................... [INSERT 5 in 24.10s]
# 01:38:24 6 of 6 START seed file jaffle_shop_raw.raw_supplies ............................ [RUN]
# 01:38:48 6 of 6 OK loaded seed file jaffle_shop_raw.raw_supplies ........................ [INSERT 65 in 23.95s]
# 01:38:48
# 01:38:48 Finished running 6 seeds in 0 hours 2 minutes and 44.47 seconds (164.47s).
# 01:38:48
# 01:38:48 Completed successfully
# 01:38:48
# 01:38:48 Done. PASS=6 WARN=0 ERROR=0 SKIP=0 TOTAL=6
すると以下のようにスキーマ名(データベース名)がdbt_project.yml
に記述したjaffle_shop_raw
へ変更することができました。
stagingレイヤのモデルの追加
ファイルの追加
Public Templateの以下にstagingレイヤのモデルのsqlファイルが格納されています。
こちらから以下のファイルをmodels/staging
フォルダに配置します。
__sources.yml
stg_customers.sql
stg_locations.sql
stg_order_items.sql
stg_orders.sql
stg_products.sql
stg_supplies.sql
sqlファイルはそのまま配置しますが、__sources.yml
は変更を加えます。
具体的にはfreshness
とloaded_at_field
に関する記述を削除した状態とします。これにより__sources.yml
は以下のようになります。
version: 2
sources:
- name: ecom
schema: jaffle_shop_raw
description: E-commerce data for the Jaffle Shop
tables:
- name: raw_customers
description: One record per person who has purchased one or more items
- name: raw_orders
description: One record per order (consisting of one or more order items)
- name: raw_items
description: Items included in an order
- name: raw_stores
description: Items included in an order
- name: raw_products
description: One record per SKU for items sold in stores
- name: raw_supplies
description: One record per supply per SKU of items sold in stores
stagingレイヤの命名規則について
ここではstaging
フォルダ配下はサブフォルダ構成となっていないため、ベストプラクティスの命名規則 stg_{source_name}__{table_name}.sql
から{source_name}
が省かれた状態となっています。
stagingするソースシステムが増えてきた場合は、サブフォルダ構成にする必要がありそうです。
materializedの設定
このstagingレイヤについてmaterializedを設定するため、dbt_project.yml
ファイルに以下を追加します。
models:
jaffle_shop:
staging:
+materialized: view
dbt runの実行でモデル作成
その後、dbt run
でモデルを作成します。
dbt run
# 13:06:43 Running with dbt=1.6.7
# 13:06:44 Registered adapter: athena=1.6.4
# 13:06:44 Unable to do partial parsing because a project config has changed
# 13:06:44 Found 6 models, 6 seeds, 12 tests, 6 sources, 0 exposures, 0 metrics, 379 macros, 0 groups, 0 semantic models
# 13:06:44
# 13:06:50 Concurrency: 1 threads (target='dev')
# 13:06:50
# 13:06:50 1 of 6 START sql view model jaffle_shop.stg_customers .......................... [RUN]
# 13:06:52 1 of 6 OK created sql view model jaffle_shop.stg_customers ..................... [OK -1 in 2.04s]
# 13:06:52 2 of 6 START sql view model jaffle_shop.stg_locations .......................... [RUN]
# 13:06:52 2 of 6 ERROR creating sql view model jaffle_shop.stg_locations ................. [ERROR in 0.01s]
# 13:06:52 3 of 6 START sql view model jaffle_shop.stg_order_items ........................ [RUN]
# 13:06:54 3 of 6 OK created sql view model jaffle_shop.stg_order_items ................... [OK -1 in 1.99s]
# 13:06:54 4 of 6 START sql view model jaffle_shop.stg_orders ............................. [RUN]
# 13:06:54 4 of 6 ERROR creating sql view model jaffle_shop.stg_orders .................... [ERROR in 0.01s]
# 13:06:54 5 of 6 START sql view model jaffle_shop.stg_products ........................... [RUN]
# 13:06:56 5 of 6 OK created sql view model jaffle_shop.stg_products ...................... [OK -1 in 1.97s]
# 13:06:56 6 of 6 START sql view model jaffle_shop.stg_supplies ........................... [RUN]
# 13:06:56 6 of 6 ERROR creating sql view model jaffle_shop.stg_supplies .................. [ERROR in 0.02s]
# 13:06:56
# 13:06:56 Finished running 6 view models in 0 hours 0 minutes and 11.74 seconds (11.74s).
# 13:06:56
# 13:06:56 Completed with 3 errors and 0 warnings:
# 13:06:56
# 13:06:56 Compilation Error in model stg_locations (models\staging\stg_locations.sql)
# Required var 'truncate_timespan_to' not found in config:
# Vars supplied to stg_locations = {}
# 13:06:56
# 13:06:56 Compilation Error in model stg_orders (models\staging\stg_orders.sql)
# Required var 'truncate_timespan_to' not found in config:
# Vars supplied to stg_orders = {}
# 13:06:56
# 13:06:56 Compilation Error in model stg_supplies (models\staging\stg_supplies.sql)
# 'dbt_utils' is undefined. This can happen when calling a macro that does not exist. Check for typos and/or install package dependencies with "dbt deps".
# 13:06:56
# 13:06:56 Done. PASS=3 WARN=0 ERROR=3 SKIP=0 TOTAL=6
# aws-vault: error: exec: Failed to wait for command termination: exit status 1
ここでエラーが発生しました。以下の2件でエラーとなっている様子です。
Required var 'truncate_timespan_to' not found in config
'dbt_utils' is undefined.
エラーに対する対処
1件目のRequired var 'truncate_timespan_to' not found in config
については、以下をdbt_project.yml
に追記して修正をします。
vars:
truncate_timespan_to: "{{ current_timestamp() }}"
2件目の'dbt_utils' is undefined.
は単純にパッケージが無いだけですので、以下をpackages.yml
に追記します。
packages:
- package: dbt-labs/dbt_utils
version: 1.1.1
その後、dbt deps
で依存パッケージをインストールします。
dbt deps
# 07:47:32 Running with dbt=1.6.7
# 07:47:33 Installing dbt-labs/dbt_utils
# 07:47:33 Installed from version 1.1.1
# 07:47:33 Up to date!
dbt runの再実行
再度、dbt run
でモデルを作成します。
dbt run
# 07:50:16 Running with dbt=1.6.7
# 07:50:16 Registered adapter: athena=1.6.4
# 07:50:16 Found 6 models, 6 seeds, 6 sources, 0 exposures, 0 metrics, 624 macros, 0 groups, 0 semantic models
# 07:50:16
# 07:50:22 Concurrency: 1 threads (target='dev')
# 07:50:22
# 07:50:22 1 of 6 START sql view model jaffle_shop.stg_customers .......................... [RUN]
# 07:50:24 1 of 6 OK created sql view model jaffle_shop.stg_customers ..................... [OK -1 in 2.06s]
# 07:50:24 2 of 6 START sql view model jaffle_shop.stg_locations .......................... [RUN]
# 07:50:26 2 of 6 OK created sql view model jaffle_shop.stg_locations ..................... [OK -1 in 1.87s]
# 07:50:26 3 of 6 START sql view model jaffle_shop.stg_order_items ........................ [RUN]
# 07:50:28 3 of 6 OK created sql view model jaffle_shop.stg_order_items ................... [OK -1 in 1.91s]
# 07:50:28 4 of 6 START sql view model jaffle_shop.stg_orders ............................. [RUN]
# 07:50:30 4 of 6 OK created sql view model jaffle_shop.stg_orders ........................ [OK -1 in 2.05s]
# 07:50:30 5 of 6 START sql view model jaffle_shop.stg_products ........................... [RUN]
# 07:50:32 5 of 6 OK created sql view model jaffle_shop.stg_products ...................... [OK -1 in 2.12s]
# 07:50:32 6 of 6 START sql view model jaffle_shop.stg_supplies ........................... [RUN]
# 07:50:34 6 of 6 OK created sql view model jaffle_shop.stg_supplies ...................... [OK -1 in 1.96s]
# 07:50:34
# 07:50:34 Finished running 6 view models in 0 hours 0 minutes and 17.49 seconds (17.49s).
# 07:50:34
# 07:50:34 Completed successfully
# 07:50:34
# 07:50:34 Done. PASS=6 WARN=0 ERROR=0 SKIP=0 TOTAL=6
stagingレイヤのモデルが作成されました。
current_timestampについて
先ほどdbt-project.yml
に追記した以下のcurrent_timestamp()
についてです。
vars:
truncate_timespan_to: "{{ current_timestamp() }}"
こちらはAthena上でクエリを実行する際には、以下のように解釈されて実行されます。
cast(now() as timestamp)
この辺りの動作はdbt-athenaの実装によるもののようです。
これを見る限り、table_type
やmaterialized
により動作を変えるような仕組みが実装されているようです。
dbt-athenaが吸収しようとしてる部分が垣間見えますので、なるべくこういったcurrent_timestamp()
などの定義済みのマクロを使用する方が恩恵を受けられるケースがありそうですね。
martsレイヤのモデル作成
ファイルの追加
Public Templateの以下にmartsレイヤのモデルのsqlファイルが格納されています。
ここからMetricflow以外のsqlファイルをmodels/marts
配下にコピーします。
customers.sql
locations.sql
order_items.sql
orders.sql
products.sql
supplies.sql
materializedの設定
このmartsレイヤについてmaterializedを設定するため、dbt_project.ymlファイル以下を追加します。
models:
jaffle_shop:
staging:
+materialized: view
marts:
+materialized: table
dbt runの実行でモデル作成
その後、dbt runでモデルを作成します。--select "marts"
とすることにより、martsレイヤのモデルだけを作成することができます。
dbt run --select "marts"
# 09:53:22 Running with dbt=1.6.7
# 09:53:22 Registered adapter: athena=1.6.4
# 09:53:22 Found 12 models, 6 seeds, 6 sources, 0 exposures, 0 metrics, 624 macros, 0 groups, 0 semantic models
# 09:53:22
# 09:53:28 Concurrency: 1 threads (target='dev')
# 09:53:28
# 09:53:28 1 of 6 START sql table model jaffle_shop.locations ............................. [RUN]
# 09:53:42 1 of 6 OK created sql table model jaffle_shop.locations ........................ [OK 5 in 14.22s]
# 09:53:42 2 of 6 START sql table model jaffle_shop.order_items ........................... [RUN]
# 09:53:57 2 of 6 OK created sql table model jaffle_shop.order_items ...................... [OK 95368 in 15.07s]
# 09:53:57 3 of 6 START sql table model jaffle_shop.products .............................. [RUN]
# 09:54:11 3 of 6 OK created sql table model jaffle_shop.products ......................... [OK 10 in 13.89s]
# 09:54:11 4 of 6 START sql table model jaffle_shop.supplies .............................. [RUN]
# 09:54:25 4 of 6 OK created sql table model jaffle_shop.supplies ......................... [OK 65 in 14.23s]
# 09:54:25 5 of 6 START sql table model jaffle_shop.orders ................................ [RUN]
# 09:54:38 5 of 6 OK created sql table model jaffle_shop.orders ........................... [OK 59652 in 12.89s]
# 09:54:38 6 of 6 START sql table model jaffle_shop.customers ............................. [RUN]
# 09:54:51 6 of 6 OK created sql table model jaffle_shop.customers ........................ [OK 939 in 12.52s]
# 09:54:51
# 09:54:51 Finished running 6 table models in 0 hours 1 minutes and 28.49 seconds (88.49s).
# 09:54:51
# 09:54:51 Completed successfully
# 09:54:51
# 09:54:51 Done. PASS=6 WARN=0 ERROR=0 SKIP=0 TOTAL=6
martsレイヤのモデルが作成されました。
ここまでのレポジトリ
ここまでを実行したGitHubレポジトリを以下に公開しています。
今回扱わなかったこと
今回は簡単のため、以下についてはまだ取り込んでいません。今後取り扱おうと思います。
- modelsのプロパティに関する記述(descriptionやtestなど)
- sourcesのfreshnessに関する記述
- MetricFlowやSemantic modelsに関する記述
まとめ
いかがでしたでしょうか。本記事がdbt-athenaでdbtを始められる方の参考になれば幸いです。