
BigQueryへのクエリ発行・管理に「dbt CLI on Windows」を使ってみる
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
DA事業本部コンサルティングチームのnkhrです。
本エントリは、Google Cloud Advent Calendar 2021の19日目の記事です。dbtを使ってBigQueryのクエリを開発・管理するための環境設定を行います。
dbtは、ELTにおいて主にTransform(データ加工)をカバーするツールで、SaaS版のdbt Cloud(Developer版はFree)とCommunity版のdbt Core があります。今回は、dbt Coreに含まれるコマンドラインインタフェース「dbt CLI」をWindows10にインストールします。
mac OSでdbt CLIによりBigQueryを操作する場合は、以下のブログが参考になります。
実行環境
環境 | バージョン |
---|---|
OS | Microsoft Windows 10 Pro |
python | 3.9.9 ※dbt CLIは2021/11時点でpython 3.6以上が必要。 |
dbt CLI | 0.21.1 ※Python 3.9.xは不具合報告もあるため、安定利用の場合は3.8.x系が良いかも |
git | 2.34.1 |
※Microsoft StoreからPythonをインストールしている場合は「C:\Users\<username>\AppData\Local\Microsoft\WindowsApps
」配下に各バージョンのPython実行用exeファイルがインストールされています。
Windowsで過去バージョンと現在バージョンの両方を使い分けたい場合は、pipenvを利用する方法があります。
pipenv --python 3.8
> pipenv shell
pythonの複数バージョン(3.8と3.9など)をインストールしている環境では、
pipenvでpythonバージョンを指定して仮想環境を立ち上げることができます
dbt CLIのインストール
dbt CLIは、homebrew、pip、sourceのいずれかで入手できます。本ブログではpipインストールを行います。
<仮想環境の作成>
> python --version
Python 3.9.9
> mkdir dbt-test
> cd dbt-test
> python3 -m venv dbt-env
python3の標準モジュール「venv(仮想環境の作成ツール)」を利用し、dbt-envという名称で仮想環境を作成します。
<仮想環境の起動/pip install>
> .\dbt-env\Scripts\activate
(dbt-env)> pip install dbt
(dbt-env)> pip freeze
インストールされたライブラリを表示
(dbt-env)> dbt --version
installed version: 0.21.1
latest version: 0.21.1
(dbt-env)> pip install --upgrade dbt
BigQuery設定
DBTのGetting Startedに従って、以下の手順を実行します。
- BigQuery用のプロジェクトを作成する
- dbtがPublicに公開しているBigQueryのデータセットを確認する
- dbt CLIから接続するためのService Accountを作成する
1. BigQuery用プロジェクト作成
[Create Project]からBigQuery用のProjectを作成する。
2. dbtのPublicデータセットを確認
dbtでは、BigQueryのチュートリアル用にPublicなデータセット「`dbt-tutorial`.jaffle_shop」を提供しています。
- プロジェクト名:dbt-tutorial
- データセット名:jaffle_shop
データセットには、以下の2テーブルが存在します。
- customers
- orders
BigQueryのコンソールの「SQL workspace」のSQLエディタで以下を実行するとテーブルが確認できます。
<データセット内の全テーブルを表示>
SELECT * FROM `dbt-tutorial`.jaffle_shop.INFORMATION_SCHEMA.TABLES
3. dbt用のService Accountを作成
GCPで[APIs & Service]コンソールへ移動し、Credentialsタブを表示します。
[CREATE CREDENTIALS] > Service Account を選択し、下記を入力してdbt用のアカウントを作成します。
- Service account name: dbt-service-account
- Role
- BigQuery Job User
- BigQuery User
- BigQuery Data Editor
作成したServcie Accountの詳細画面において、[KEYS]タブからKEYを追加([ADD KEY] > Create new key)し 、JSONファイルをダウンロードします。ダウンロードしたJSONファイルは適切な名前に変更して~/.dbt/フォルダ配下に格納します。(後続のprofile.yaml設定で指定するファイル)
dbt project作成
Geting Startedのチュートリアルを参考に、dbtプロジェクトを作成します。チュートリアルではGitHubにリポジトリを作成してコードを管理していますが、今回はGitHubでのリポジトリ作成やコード管理の手順を省略しています。
dbt init
コマンドでプロジェクトの初期設定(必要なフォルダや設定テンプレートの作成)を行います。
> cd dbt-test
> .\Scripts\activate
> dbt init test-project
> cd test-project
projectの設定を変更
dbt_project.yml
ファイルの以下の箇所を修正します。
(修正前)
name: 'my_new_project'
…
profile: 'default'
…
models:
my_new_project:
(修正後)
name: 'test_project'
…
profile: 'test_project'
…
models:
test_project:
profile: XXX
に指定した「XXX」は、後続で設定するprofile.yamlのフィールド名になります。defaultのまま変更しない場合は、profile.yamlのdefaultフィールドに接続情報を記入します。- プロジェクト名(name)は、
'^[^\\d\\W]\\w*$'
の正規表現に一致している必要があるため、記号はアンダーバーのみ利用できます。
profileの設定(BigQuery接続設定)
dbtインストール後にHOME配下に「.dbt」フォルダが作成されています(~/.dbt)。この設定フォルダ内のprofile.yaml
にBigQueryの設定情報を記入します。
Profile修正後に「dbt debug」コマンドにより接続確認を行います。
> cd ~/.dbt
> vim profile.yaml
(テキストエディタでprofile.yamlを編集する)
> cd dbt-env
> .\Scripts\activate
> cd .\test-project
> dbt debug
…
All checks passed!
以下は設定イメージです。
- projectには接続先BigQueryのプロジェクトIDを設定。default設定は残して置いたままでもよい。
- datasetはBigQueryのデータセット名を設定
BigQueryデータセットとは何だ?という方は、以下のブログが参考になります。
dbtによるクエリ作成と実行
ここまでの手順でBigQueryの環境と、BigQueryを操作するためのdbtの環境が作れました。初期設定後のプロジェクトでdbt run
を実行すると、下記のリソースが作成されます。
- データセット: dbt_test
- Profileで指定したデータセットが存在しない場合、作成される
- テーブル: my_first_dbt_model
- <project folder>/models/example/schema.yamlに定義したテーブル
- ビュー: my_second_db_model
テーブルや処理の定義を変える場合は、以下のファイルを修正します。
- dbt_project.ymlの「models」フィールド
example: +materialized: view
- 上記はmodels/example配下に作成されるオブジェクトはデフォルトでビューとする定義です。他の設定としては、table, incremental, ephemeralが指定できます。
- <project folder>/models/配下のファイルの修正、追加
dbtによるテーブル作成
<dbt_project.yml変更>
models:
test_project:
# example: (コメントアウト)
# +materialized: view (コメントアウト)
customer:
+materialized: table
<モデルの追加>
以下のファイルを作成します。
/models/customer/schema.yaml (Yamlファイルの名前は任意) /models/customer/customers.sql /models/customer/finals.sql
models/exampleは削除します。(残っている場合、example定義のテーブル・ビューも作成されます)
ファイル内容(公式サイトチュートリアルのコードを分解して利用※表示は▶をクリック)
- schema.yaml
version: 2
models:
- name: customers
description: "customer model"
columns:
- name: customer_id
data_type: STRING(10)
tests:
- unique
- not_null
- name: first_name
data_type: STRING(20)
- name: last_name
data_type: STRING(20)
- name: finals
columns:
- name: customer_id(10)
data_type: STRING(10)
tests:
- unique
- not_null
- name: first_name
data_type: STRING(20)
- name: last_name
data_type: STRING(20)
- name: first_order_date
data_type: DATETIME
- name: most_recent_order_date
data_type: DATETIME
- name: number_of_orders
data_type: NUMERIC(10)
- customers.sql
with customer_us AS (
select
id as customer_id,
first_name,
last_name
from `dbt-tutorial`.jaffle_shop.customers
)
SELECT * FROM customer_us
- final.sql
with orders as (
select
id as order_id,
user_id as customer_id,
order_date,
status
from `dbt-tutorial`.jaffle_shop.orders
),
customer_orders as (
select
customer_id,
min(order_date) as first_order_date,
max(order_date) as most_recent_order_date,
count(order_id) as number_of_orders
from orders
group by 1
)
select
customers.customer_id AS customer_id,
customers.first_name AS first_name,
customers.last_name AS last_name,
customer_orders.first_order_date AS order_date,
customer_orders.most_recent_order_date AS most_recent_order_date,
coalesce(customer_orders.number_of_orders, 0) as number_of_orders
from customers
left join customer_orders using (customer_id)
モデルの実行
> dbt test
> dbt run
…
Completed successfully
Done. PASS=2 WARN=0 ERROR=0 SKIP=0 TOTAL=2
新たに定義した2テーブルが、BigQuery上に作成されます。
ログ設定の変更
ログの出力先や出力レベルの変更方法を調べました。
実行ログの出力先を変更
projectの設定ファイル(dbt_project.yaml)内のlog-path
で指定します。デフォルトは「<project folder>/logs/dbt.log
」です。
下記の設定例では、ユーザのHOMEフォルダ配下のlogsフォルダに「dbt.log」ファイルを出力します。
log-path: C:\Users\<user name>\logs
Debugログの出力
debugログの出力のON/OFF切り替えができます。profile.yamlで定義するか実行時のオプションとして指定できます。
<profile.yamlの定義>
config:
debug: true
test_project:
target: dev
outputs:
……
<実行時のオプション>
> dbt --debug run
出力フォーマット変更
出力フォーマットをJSONに変更すれば、JSONラインとしてログが出力されます。
<profile.yamlの定義>
config:
LOG_FORMAT: json
<実行時のオプション>
> dbt --log-format json run
ログのTimezoneを変更
デフォルトでは、UTCのTimezoneでログが出力される。2021/12時点ではログ出力時刻のTimezoneをUTC→JSTに変更する設定はなさそうです。
ワークフローの設定
dbtではテーブルの作成順序をref関数により設定できます。ref関数で別のモデル(modelsフォルダ下のSQLファイルの名称と対応)を指定し、モデル間の依存関係を定義することで実行順序が制御されます。
CLIではスケジュール機能を含んでいないため、dbt runをcronに設定したり、airflowやその他のワークフローツールで実行する必要があります。依存関係の可視化は、dbt Cloudでは簡易な可視化が可能ですが、CLIではThird partyのカタログツールなどと組み合わせる必要がありそうです。
まとめ
dbtは、プログラマティックにLakeHouseを管理する場合の機能を十分に備えているようです。また、開発・本番の環境ごとの定義の切り替えや、テストも実施できるため、GitHubを利用したBuild/Deplopy開発フローに適用できそうです。
LakeHouseの開発、管理ツールとして、利用を検討してみてもよいかなと思います。