Jupyter Notebook 上で dbt を使いたい
はじめに
現在の開発環境では、VSCode 上で dbt Core を使ってモデリングを行っています。しかし、基本的にクエリを実行するたびに前回の結果が上書きされてしまうため、「データを継続的に見ながら開発するのが少し不便だな」と感じていました。
もともと私はデータアナリストとしてのバックグラウンドがあり、探索的なデータ分析には Jupyter Notebook をよく活用していました。そこで、「もし Jupyter Notebook 上で dbt のモデリングができれば、もっと快適に開発できるのではないか?」と思いました。
自分の悩みは世界の誰かが同じ悩みを持っていると思って調べましたが、使えるライブラリはありませんでした。
↓それっぽい感じでしたが、自分の環境では動きませんでした。
なので、自分で作りました( ´∀`)
前提条件
- VSCode 上で dbt Core を使った開発環境がある
- VSCode 上で Jupyter Notebook を利用できる
dbt-magicsとは?
dbt-magics
は、Jupyter Notebook で dbt
を操作するためのカスタムマジックコマンドです。
これにより、以下のようなことが可能になります
-
%%dbt_show
を使って dbtのクエリをそのまま実行 - クエリ結果を Pandas DataFrame として取得・変数に格納
-
%%dbt_compile
で SQL をdbt
のコンテキストでコンパイル
インストール方法
-
dbt-magics
をインストールします
pip install git+https://github.com/1210yuichi0/dbt-magics.git
- Jupyter Notebook 上でマジックコマンドを読み込みます
%load_ext dbt_magics
使い方とユースケース
データのプレビュー
%%dbt_show
SELECT * FROM {{ ref('sales_data') }}
Jupyter Notebook 上に直接テーブルが表示されるので、確認が非常にスムーズです。
データを変数に保存して加工
クエリの結果を DataFrame に保存して、Python で加工することも可能
%%dbt_show customer_df
SELECT * FROM {{ ref('customer_data') }}
その後は普通に customer_df.head()
のように使えます。
SQLのコンパイルだけ行いたい場合
%%dbt_compile
SELECT * FROM {{ ref('inventory') }}
dbt compile
の出力をその場で確認できます。エラーの早期発見に便利です。
結果をクリップボードにコピーする
以下のように %%dbt_show copydf を使うことで、クエリ結果を クリップボードにコピー することができます
%%dbt_show copydf
SELECT * FROM {{ ref('customer_data') }}
これにより、実行結果をそのまま Excel やスプレッドシートなどに貼り付けて共有するのが簡単になります。
よく使っている dbt macro
Jupyter Notebook 上で dbt を使用する際に合わせてよく利用している dbt macro を紹介します
※ BigQuery を前提にしています。
dbt モデルのカラム情報を取得する
これから利用するdbt モデルのパーティションやクラスタのカラムを確認するために使っている
{{ get_table_columns(source("jaffle_shop", "customers")) }}
{{ get_table_columns(ref("stg_customers")) }}
{% macro get_table_columns(model) %}
select
c.ordinal_position as column_no,
c.column_name,
d.description,
c.data_type,
c.is_partitioning_column as partition_by,
c.clustering_ordinal_position as cluster_by
from `{{ model.schema }}`.INFORMATION_SCHEMA.COLUMNS as c -- fmt: off
left join
`{{ model.schema }}`.INFORMATION_SCHEMA.COLUMN_FIELD_PATHS as d -- fmt: on
on c.column_name = d.column_name
and c.table_name = d.table_name
where c.table_name = '{{ model.identifier }}'
order by c.ordinal_position
{% endmacro %}
dbt モデルのカラムサンプル取得する
これから利用するdbt モデルのカラムサンプルを確認するために使っている
dbt_utils
のパッケージが必要。
結構乱暴なクエリなので、コストと相談して実行ください。
{{ get_column_samples(source("jaffle_shop", "customers")) }}
{{ get_column_samples(ref("stg_customers")) }}
{% macro get_column_samples(model, sample_size=10) %}
{% set columns = dbt_utils.get_filtered_columns_in_relation(from=model) %}
with
column_info as (
select
c.ordinal_position as column_no, c.column_name, d.description, c.data_type,
from `{{ model.schema }}`.INFORMATION_SCHEMA.COLUMNS c -- fmt: off
left join
`{{ model.schema }}`.INFORMATION_SCHEMA.COLUMN_FIELD_PATHS d -- fmt: on
on c.column_name = d.column_name
and c.table_name = d.table_name
where c.table_name = '{{ model.identifier }}'
),
sample_values as (
{% for col in columns %}
select '{{ col }}' as column_name, cast({{ col }} as string) as value
from (select {{ col }} from {{ model }} where {{ col }} is not null limit {{ sample_size }})
{% if not loop.last %}
union all
{% endif %}
{% endfor %}
)
select
ci.column_no,
ci.column_name,
ci.description,
ci.data_type,
string_agg(distinct sv.value, " | ") as samples
from column_info ci
left join sample_values sv on ci.column_name = sv.column_name
group by ci.column_no, ci.column_name, ci.description, ci.data_type
order by ci.column_no asc
{% endmacro %}
おわりに
dbt-magics
を使えば、Jupyter Notebook 上で dbt
の開発やデバッグがとても快適になります。特に「素早くデータを確認したい」「クエリの動作を試したい」といったシーンで効果を発揮するでしょう。
普段の dbt 開発に Jupyter Notebook を取り入れることで、より柔軟で効率的なワークフローを実現してみてください。
※ 初めて作った Python パッケージなので、優しいフィードバックをお待ちしています!
参考
Discussion