dbt-athenaで既存のGlueテーブルをソーステーブルに使う
データアナリティクス事業本部 機械学習チームの鈴木です。
機械学習モデル作成用のデータマート作成に、dbt-athenaを使いたく、仕様について調べています。
dbtではsource
を使うことで既にデータウェアハウスにロードされているデータに対して名前をつけてDAGに取り込むことが可能です。もちろんdbt-athenaでも利用が可能です。
dbt-athenaの場合、Glueデータカタログ上の既存のGlueテーブルをソーステーブルとして使うことになりますが、定義ファイルの細かい書き方などちょっと気になるところがあったので試してみました。
この記事の内容について
Glueデータカタログ上の既存のGlueテーブルをsourceとして指定するためのymlファイルを作成し、ソーステーブルのデータを使ってモデルを作成しました。
特に、ymlファイルをどのように書くと、AthenaでどんなSQLが実行されるのかのイメージを持ちたかったため、ymlファイルとクエリ履歴の比較もしました。
環境構築
以前公開した以下の記事の方法でEC2上にdbt-coreとdbt-athena-communityをインストールして検証しました。
dbtのバージョンは以下になります。
- dbt Core:1.5.6
- dbt-athena-community:1.5.1
Glueテーブルは以下のように、S3バケットに配置したUCI Machine Learning RepositoryのIris Data Setを検索できるテーブルを作成しておきました。
このデータセットは、下記リンクにて公開されています。
https://archive.ics.uci.edu/ml/datasets/iris
やってみる
1. ソーステーブルを定義する
models/
にiris.yml
を以下のように作成しました。
version: 2 sources: - name: iris_raw database: awsdatacatalog schema: cm-nayuts-sample-db tables: - name: iris
プロパティは以下のガイドを参考にしました。
name
およびtables
はほかのコネクタの場合と同様に考えればよかったのですが、迷ったのはdatabase
とschema
でした。
この2つについては、profiles.yml
に記載する内容を説明した、dbt-athenaレポジトリのConfiguring your profileに記載の事項と同様で良いだろうと考え、database
にはawsdatacatalog
を、schema
にはGlueデータベース名を設定しました。
2. ソーステーブルを参照するモデルを定義する
続いて、集計後のマートとして、モデルを以下のiris_mart.sql
のように定義しました。
select class, avg(sepal_length) as avg_sepal_length, avg(sepal_width) as avg_sepal_width, avg(petal_length) as avg_petal_length, avg(petal_width) as avg_petal_width from {{ source('iris_raw','iris') }} group by class
{{ source('iris_raw','iris') }}
としてソーステーブルを指定しました。
なお、今回はプロジェクトのdbt_project.yml
ファイルにて、models
ディレクトリのmaterialized
はtable
を指定しています。
3. モデルの作成を実行する
モデルを作成しました。
dbt run
Athenaのクエリ履歴を確認すると、以下のように2つのSQLが実行されていました。
-- /* {"app": "dbt", "dbt_version": "1.5.6", "profile_name": "test_project", "target_name": "dev", "node_id": "model.test_project.iris_mart"} */ create table "awsdatacatalog"."cm-nayuts-sample-db"."iris_mart" with ( table_type='hive', is_external=true,external_location='s3://s3_data_dirで指定したパス/cm-nayuts-sample-db/iris_mart/c1a7d67b-b6fc-4286-ba74-6511204e99f5', format='parquet' ) as select class, avg(sepal_length) as avg_sepal_length, avg(sepal_width) as avg_sepal_width, avg(petal_length) as avg_petal_length, avg(petal_width) as avg_petal_width from "awsdatacatalog"."cm-nayuts-sample-db"."iris" group by class
※ s3_data_dirで指定したパス
は~/.dbt/profiles.yml
で指定したs3_data_dir
キーのバリューのことです。
alter table `cm-nayuts-sample-db`.`iris_mart` set tblproperties ('classification' = 'parquet')
1つ目のSQLでハイライトしたように、database
とschema
の値が使われています。
マートテーブルは以下のように作成されました。
空行が入っているのはソーステーブルのデータセットに元々空行があるためです。
4. ソーステーブルの定義を変えてSQLを確認する
以下は少し細かい確認ですが、database
の記載によって、実行される1つ目のSQLがどう変わるのか気になったので確認しました。
まずは指定しないパターンです。
version: 2 sources: - name: iris_raw # database: awsdatacatalog schema: cm-nayuts-sample-db tables: - name: iris
以下のようにデフォルト値としてawsdatacatalog
が設定されました。
-- /* {"app": "dbt", "dbt_version": "1.5.6", "profile_name": "test_project", "target_name": "dev", "node_id": "model.test_project.iris_mart"} */ create table "awsdatacatalog"."cm-nayuts-sample-db"."iris_mart" with ( table_type='hive', is_external=true,external_location='s3://s3_data_dirで指定したパス/cm-nayuts-sample-db/iris_mart/fae19913-af30-4fe6-9547-87fe13bafc1b', format='parquet' ) as select class, avg(sepal_length) as avg_sepal_length, avg(sepal_width) as avg_sepal_width, avg(petal_length) as avg_petal_length, avg(petal_width) as avg_petal_width from "awsdatacatalog"."cm-nayuts-sample-db"."iris" group by class
次にawsdatacatalog
以外を指定したパターンです。
version: 2 sources: - name: iris_raw database: dummy schema: cm-nayuts-sample-db tables: - name: iris
指定した値が設定されました。awsdatacatalog
以外のデータソースを使いたいときにも使用できますね。
-- /* {"app": "dbt", "dbt_version": "1.5.6", "profile_name": "test_project", "target_name": "dev", "node_id": "model.test_project.iris_mart"} */ create table "awsdatacatalog"."cm-nayuts-sample-db"."iris_mart" with ( table_type='hive', is_external=true,external_location='s3://s3_data_dirで指定したパス/cm-nayuts-sample-db/iris_mart/65a38014-9696-43cb-bac6-776b6b350b62', format='parquet' ) as select class, avg(sepal_length) as avg_sepal_length, avg(sepal_width) as avg_sepal_width, avg(petal_length) as avg_petal_length, avg(petal_width) as avg_petal_width from "dummy"."cm-nayuts-sample-db"."iris" group by class
最後に
dbt-athena-communityで既存のGlueデータカタログをソーステーブルとして利用する方法や定義ファイルの書き方について確認しました。
dbtの基本的な機能ですが、dbt-athenaでも使えることが確認できました。これにより、既にデータレイクに連携されているデータからモデルを作成することができますね。
参考になりましたら幸いです。