dbt Python Model + Snowpark for Python を動かしてみた
📜 この記事は
dbt Advent Calendar 2022 Day 24 の記事になります。Snowflake で Sales Engineer をしております、@tmasuo がお届けします。
この記事で触れる Snowflake の各機能のリリース状態は 2022 年 12 月 1 日時点に基づきます。
Inspired by ...
Advent Calendar って良い文化ですよね。Snowflake Advent Calendar ばかりに投稿していましたが、こちらの記事は dbt Advent Calendar の以下の記事からインスピレーションを受けました。どちらも dbt Python Model を Snowflake と一緒に動かしてもらってます。
これは試さないといけない!! という使命感と、どうやって動いているんだろう? という純粋な興味を成仏させるための記事となっています。
またどちらの Advent Calendar に投稿するかちょっと悩みましたが、dbt 側がちょうど 1 枠だけ空いていたのでお邪魔させていただきました。
🐍 dbt Python Model + Snowpark for Python
dbt Python Model の公式ドキュメントはこちらです。
そして Snowflake と一緒に動かす、という前提に立ったとき重要なのが以下の点と思います。
Since all dbt transformation is pushed down to a data platform, you are naturally limited by what your data platform allows.
つまり、dbt Python Model + Snowflake でできることは、Snowflake 上でどんな Python の開発ができるかということに大きく依存するのです。
つまり、Snowpark for Python で何ができるか?という点です。
ということで dbt Python Model + Snowpark for Python を動かしてみてその動作原理を確認しつつ、Snowflake で動作させるメリットを考察してみたいと思います。
⚙️ 動かしてみる
以下の Quickstart コンテンツを動かしてみました。dbt Python Model + Snowpark for Python の動作原理に迫る内容となっています。
環境準備
1. Overview と 2. Create the dbt Project の部分です。
Anaconda の環境を作って dbt インストールして Project を初期化してそのまま実行するだけです。なんの変哲もないですね。早速次に進みます。
シンプルなモデルの動き
3. Create a Simple Python Model では非常にシンプルな、以下のモデルを実行しています。
def model(dbt, session):
# Must be either table or incremental (view is not currently supported)
dbt.config(materialized = "table")
# DataFrame representing an upstream model
df = dbt.ref("my_first_dbt_model")
return df
環境準備してから、特に何も手を加えずに私の環境では Python Model が動いてしまいました。
この動作原理を 4. Understand How the Simple dbt Python Model Works ではクエリ履歴から追っています。
結論から言うと、dbt Python Model は Python Stored Procedure で動いています。
Snowpark for Python はいくつかのコンポーネントから構成されており、Python Stored Procedure では Snowflake 上でネイティブな Python コードを実行することが可能です。
Snowpark for Python の概要およびできることは以下でまとめています。
このように動くことのメリットとしては以下のような点があるかなと思いました。
Python 実行環境を別途用意する必要がない
まず Snowflake では Python のネイティブコードの実行が可能です。そのため追加で何かしらのソリューションと用意して連携、といったことがなく dbt Python Model を実行できる点は環境構築の観点からメリットとなります。
さらに Snowflake は Anaconda によって構築されているサードパーティパッケージの利用が可能です。(詳細はこちら、規約への合意などいくつか手順が必要)
これによりこちらにリストアップされたライブラリは依存関係の追加が必要なく利用できます。なので、dbt Python Model が開発された大きな背景でもある Python の拡張性の高さをすぐ活用できる点も良いなと思いました。
Snowpark for Python との連携
Python でのデータエンジニアリング、ということで当然ながら Snowpark for Python との連携はメリットとなります。複雑なデータ加工を DataFrame 処理でハンドリングしたり、Python UDF を利用することで予測値をパイプラインで付与するなどのユースケースが考えられます。
また DataFrame 処理により、SQL では Jinja テンプレートの Macro に頼らざるを得なかった部分を純粋な Python コードで記述できるといったこともできます。
以下では Jaffle Shop (dbt のサンプルプロジェクト) を Snowpark で記載した場合のサンプルと比較しています。
UDF も加えたときの動き
前述したメリットの 1 つである Python UDF を dbt Python Model で記載した場合ですが、その動作も確認しています。
5. Create a Python Model with a UDF でモデルを定義しています。Python UDF の実装自体は極めてシンプルなものです。
こちらも同様に動作原理を 6. Understand How the dbt Python Model with a UDF Works で確認しています。
まずモデルが Python Stored Procedure として実行されるのは特に変わりません。
ただ、Python UDF については Templorary の関数として作成されます。この Temporary の関数を用いて Table が Materialize されるといった仕組みです。
CREATE
TEMPORARY FUNCTION "DEMO_DB"."DEMO_SCHEMA".SNOWPARK_TEMP_FUNCTION_SI69CC7X3M(arg1 BIGINT)
RETURNS BIGINT
LANGUAGE PYTHON
RUNTIME_VERSION=3.8
PACKAGES=('cloudpickle==2.0.0')
HANDLER='compute'
AS $$
## 省略 - 実際は生成された Python コードがこちらに
$$
関数は Temporary のため、セッションが破棄されると同時に消滅します。(なので DROP も実行されない)
内部的な挙動は少し複雑になりましたが、Python UDF も利用できるのはパイプラインの拡張性の上では極めて強力ですね。
✅ さいごに
dbt Python Model + Snowpark for Python により、dbt を活用したデータパイプラインを Python でも構築することができることができるようになりました。
これにより、SQL と Python という言語の選択肢を提供し、かつ Snowflake では SQL も Python どちらもネイティブに動くため極めてシームレスな体験を提供できる点がメリットかなと思いました。
dbt Python Model はまだ機能拡充中であり、SQL Model でできる内容をすべてカバーできていないようですが、今後の展開が楽しみです。ぜひお試しください!
Discussion