Slide 1

Slide 1 text

© LayerX Inc. dbt Pythonモデルで実現するSnowflake活⽤術 Tokyo dbt meetup #12 株式会社LayerX バクラク事業部 機械学習‧データ部 平⽥ 拓也

Slide 2

Slide 2 text

© LayerX Inc. 2 ⾃⼰紹介 平田 拓也 (@TrsNium) 株式会社LayerX バクラク事業部 機械学習・データ部 DataOps チーム データエンジニア 2023年11月よりLayerXにjoin 普段はデータ基盤の運用開発を中心にやっています !

Slide 3

Slide 3 text

3 © LayerX Inc. 「すべての経済活動を、デジタル化する。」をミッションに、AI SaaSとAI DXの事業を展開 事業紹介 バクラク事業 企業活動のインフラとなる業務を 効率化するクラウドサービス Fintech事業 ソフトウェアを駆使したアセットマネジ メント‧証券事業を合弁会社にて展開 AI‧LLM事業 社内のナレッジやノウハウをデータ ベース化するAIプラットフォーム AI SaaSドメイン AI DXドメイン

Slide 4

Slide 4 text

⽬次 Agenda ● はじめに ● Python Modelの基礎知識 ● Python Modelの仕組み(Snowflake編) ● Python Modelの便利な機能と使い⽅ ● テストとパフォーマンスの課題 ● Snowflake環境でのログ出⼒と重要性 ● Future Works と今後の展望

Slide 5

Slide 5 text

⽬次 Agenda ● はじめに ● PythonModelの基礎知識 ● Python Modelの仕組み(Snowflake編) ● Python Modelの便利な機能と使い⽅ ● テストとパフォーマンスの課題 ● Snowflake環境でのログ出⼒と重要性 ● Future Works と今後の展望

Slide 6

Slide 6 text

© LayerX Inc. 6 dbt Python Model とは? はじめに 概要 ● dbt Python Model は、従来の SQL モデルに加え、Python でデータ変換ロジックを記述できる機能です。 def model(dbt, session): # モデル設定(例: テーブルとしてマテリアライズ) dbt.config(materialized='table') # シンプルなデータ取得処理 return session.sql("SELECT * FROM source_table") models/example_python_model.py source: source_table model: example_python_model model: other_sql_model

Slide 7

Slide 7 text

© LayerX Inc. 7 dbt Python Model で実現できること はじめに 柔軟なデータ変換 ● Python の豊富なライブラリやロジックを利用可能 ● API 連携や複雑なデータ整形が容易に実装できる dbt のエコシステムとの統合 ● マクロ、テスト、ドキュメント生成など、既存の dbt機能をそのまま活用 ● SQLモデルと同様に依存関係管理が可能

Slide 8

Slide 8 text

© LayerX Inc. 8 対応プラットフォーム & 実⾏環境 はじめに 対応プラットフォーム ● dbt Python Modelは、Snowflake, BigQuery, Databricksなどがサポートされている 各プラットフォームの実行環境 ● Snowflake ○ Warehouse 上で実行され、Snowpark API を利用して処理が行われる ● BigQuery ○ Python モデルは Dataproc 上の PySpark ジョブとして実行され、 BigQuery のテーブルやビューと連携して処理結果を返す ● Databricks ○ Databricks 環境上で PySpark コードとして実行される

Slide 9

Slide 9 text

© LayerX Inc. 9 深堀する運⽤の課題と取り組み はじめに ● 弊社では、dbt Python Model を部分的に活用していますが、その運用の中で様々な課題に直面してきました。 ● まず、dbt Python Model がどのように動作する仕組みについてご紹介し、その内部処理の流れを明らかにします。 ● 次に、Snowflake 環境における実行の特徴、特に Snowpark API を活用したデータ処理の詳細なプロセスについてご説明します ● さらに、テスト、デバッグ 、ログ出力に関して、 実際に直面した課題と、それらに対する改善策や工夫のポイントをお話しします。 ● 最後に、これらの課題を踏まえた今後の展望として、 Programmatic Invocations の活用やテスト環境の整備など、次のステップに向けた取 り組みについてご紹介します。

Slide 10

Slide 10 text

⽬次 Agenda ● はじめに ● Python Modelの基礎知識 ● Python Modelの仕組み(Snowflake編) ● Python Modelの便利な機能と使い⽅ ● テストとパフォーマンスの課題 ● Snowflake環境でのログ出⼒と重要性 ● Future Works と今後の展望

Slide 11

Slide 11 text

© LayerX Inc. 11 .py ファイルがモデルと認識されるまでの流れ Python Modelの基礎知識 全体の流れ Pythonモデル定義(.pyファイル) 静的解析 (AST解析) コンパイル ターゲット環境(例: Snowflake)で実⾏ なぜ静的解析をするのか? ● Pythonコードを実行せずに「構造」を把握することで、予期せぬ副作用や 実行時エラーを防止 ● 再現性のある、信頼性の高いモデル定義を実現 静的解析のメリットと制約 ● メリット : コードがどのように書かれているか(関数や変数の配置な ど)を、実際に実行する前にしっかり確認できる → これにより、予期せぬ動作やエラーを未然に防ぐことが可能に ! ● 制約: 動的な変数(envやvarsなど)や実行時ロジックは解析対象外

Slide 12

Slide 12 text

© LayerX Inc. 12 静的解析とASTの例 Python Modelの基礎知識 ● Pythonの静的解析には astモジュールが利用可能 ● ast.parse(source_code)を使うと、ソースコードが抽象構文木 (AST)に変換され、コードをツリー構造で扱うことができる import ast source_code = """ x = 42 def hello(): message = "Hello, dbt!" print(message) """ tree = ast.parse(source_code) print(ast.dump(tree, indent=4)) Module( body=[ Assign(targets=[Name(id="x", ctx=Store())], value=Constant(value=42)), FunctionDef( name="hello", args=arguments( posonlyargs=[], args=[], kwonlyargs=[], kw_defaults=[], defaults=[] ), body=[ Assign( targets=[Name(id="message", ctx=Store())], value=Constant(value="Hello, dbt!"), ), Expr( value=Call( func=Name(id="print", ctx=Load()), args=[Name(id="message", ctx=Load())], keywords=[], ) ), ], decorator_list=[], ), ], type_ignores=[])

Slide 13

Slide 13 text

© LayerX Inc. 13 AST解析実装の詳細 Python Modelの基礎知識 ソースコードの読み込みと AST生成 ● ソースコードを文字列として読み込み、 ast.parse() によりASTを作成 カスタムAST Visitorの利用 ● AST Visitor とは? : AST Visitor は、AST の各ノードを訪問し、必要な情報を取り出すためのクラス ● ast.NodeVisitor を継承したクラスを用いて、 AST を巡回しながら、モデル定義に必要なノード(例 : 関数定義、変数代入、 dbt.ref や dbt.config などの dbt 特有の呼び出し)を抽出 参考 ● dbt-core/core/dbt/parser/models.py

Slide 14

Slide 14 text

© LayerX Inc. 14 コンパイルフェーズとターゲット環境での実⾏ Python Modelの基礎知識 コンパイルフェーズ ● dbt は、PythonコードをAST解析により解析し、そこで抽出された定義を元にモデルオブジェクトを生成 ● その過程で、dbt.ref や dbt.config などのdbt固有の関数が評価され、必要な変数の置換やマクロの展開が行われ、最終的に SQLやス トアドプロシージャに変換される ターゲット環境(Snowflake)での実行 ● 変換されたモデルは、 Snowflake上でストアドプロシージャとしてラップされ、実際に実行される ● 実行中は、プロシージャ内でデータの処理が行われ、その結果が最終的にテーブルなどに保存される

Slide 15

Slide 15 text

© LayerX Inc. 15 マクロ評価と変数管理の注意点 Python Modelの基礎知識 マクロ評価の注意点 ● コンパイル時はmodel() の実際の実行は行われず、コード構造から必要な情報のみが抽出される ● 動的な変数(例 : env や vars)は直接扱えないため、代わりに schema.yml や静的な設定で値を渡す必要がある version: '2' models: - name: workspace__example__dbt_meetup config: schema: example database: "{{ var(target.name)['database'][workspace] }}" alias: dbt_meetup foo: "{{ var(target.name)[example][foo] }}" var: "{{ var(target.name)[example][foo] }}" def model(dbt, session): dbt.config(materialized='table') foo = dbt.config.get('foo') var = dbt.config.get('var') … return df

Slide 16

Slide 16 text

⽬次 Agenda ● はじめに ● Python Modelの基礎知識 ● Python Modelの仕組み(Snowflake編) ● Python Modelの便利な機能と使い⽅ ● テストとパフォーマンスの課題 ● Snowflake環境でのログ出⼒と重要性 ● Future Works と今後の展望

Slide 17

Slide 17 text

© LayerX Inc. 17 SnowflakeにおけるPython Modelの概要 Python Modelの仕組み(Snowflake編) Python Modelの実行方法 ● Pythonコードは、Snowflake上でストアドプロシージャとして実行 される ● use_anonymous_sproc を True にした場合、匿名ストアドプロ シージャが利用される ○ メリット : 実行が高速になり、クエリ履歴がクリーンに保た れる Snowflakeとの連携 ● dbt のコンパイルフェーズで、 Pythonコードが AST 解析・変換さ れ、最終的な SQL やストアドプロシージャに変換される ● 変換されたSQL/ストアドプロシージャーが Warehouse上で実行 される Pythonモデル定義(.pyファイル) 静的解析(AST)/コンパイル 変換されたSQL/ストアドプロシージャ Warehouse 上で実⾏ Snowpark API を利⽤したデータ処理 結果をテーブルに保存

Slide 18

Slide 18 text

© LayerX Inc. 18 プロシージャ内での処理の詳細 Python Modelの仕組み(Snowflake編) データマテリアライズまでの流れ ● dbt Python Model の model 関数が実行され、加工された データが得られる ● 取得したデータは、 Snowparkのsave_as_table メソッドを 用いてSnowflake上にマテリアライズされる dbt内部ロジックとの統合 ● dbt.ref, dbt.config, など、dbt固有の関数により、上流モデ ルの解決や差分更新、データ変換処理が統合され、 dbtモ デルとして動作する プロシージャーの実⾏ model(dbt, session) の実⾏ materialize() 呼び出し save_as_table でマテリアライズ

Slide 19

Slide 19 text

© LayerX Inc. 19 コード例 ‒ Python Modelとdbt内部ロジック Python Modelの仕組み(Snowflake編) def model(dbt, session): dbt.config(materialized='table') # 上流モデルを参照(コンパイル時に⽣成されるロジックによりリソース解決) df = dbt.ref("my_first_dbt_model") return df # 以降のコードはコンパイル時に⾃動で⽣成される def ref(*args, dbt_load_df_function): refs = {"my_first_dbt_model": "DEMO_DB.DEMO_SCHEMA.my_first_dbt_model"} key = ".".join(args) return dbt_load_df_function(refs[key]) # 略: source(), config, this, dbtObj などの実装

Slide 20

Slide 20 text

© LayerX Inc. 20 コード例 ‒ エントリーポイントとマテリアライズ処理 Python Modelの仕組み(Snowflake編) def materialize(session, df, target_relation): import pandas if isinstance(df, pandas.core.frame.DataFrame): df = session.createDataFrame(df) # テーブルとして結果を保存する df.write.mode("overwrite").save_as_table("DEMO_DB.DEMO_SCHEMA.my_first_python_model", table_type='') def main(session): dbt = dbtObj(session.table) df = model(dbt, session) materialize(session, df, dbt.this) return "OK"

Slide 21

Slide 21 text

⽬次 Agenda ● はじめに ● Python Modelの基礎知識 ● Python Modelの仕組み(Snowflake編) ● Python Modelの便利な機能と使い⽅ ● テストとパフォーマンスの課題 ● Snowparkライブラリに関する課題 ● Snowflake環境でのログ出⼒と重要性 ● Future Works と今後の展望

Slide 22

Slide 22 text

© LayerX Inc. 22 Python Modelの便利な機能と使い⽅ Python Modelの便利な機能と使い⽅ ● dbt Python Modelは、Pythonならではの柔軟なデータ操作が可能 ● SQLモデルと同様に、 dbtの便利な関数・マクロを活用できる ○ dbt.is_incremental, dbt.ref など ● インクリメンタル更新により、差分のみの処理が実現できる

Slide 23

Slide 23 text

© LayerX Inc. 23 dbt.is_incremental の活⽤ Python Modelの便利な機能と使い⽅ インクリメンタル実行の判定 ● dbt.is_incremental を使い、現在の実行が初回か差分更新かを判定可能 実用例 ● 既存テーブルから最新の更新時刻を取得 ● その時刻を元に新たな開始時刻として設定し、新規データのみ取得 参考 ● https://docs.getdbt.com/docs/build/incremental-models def model(dbt, session: Session) -> DataFrame: # モデルをインクリメンタルとして設定(unique_keyも指定) dbt.config(materialized='incremental', unique_key='id') # 初回実⾏時は固定の開始⽇時(例: 2024-09-01)からデータ取得 start_time = int(time.mktime(datetime.date(2024, 9, 1).timetuple())) # インクリメンタル実⾏時は、既存データの最終更新時刻から開始時刻を調整 if dbt.is_incremental: query = f"SELECT EXTRACT(EPOCH FROM MAX(updated_at)) FROM {dbt.this}" last_updated_at = int(session.sql(query).collect()[0][0]) start_time = last_updated_at - 60 # 1分前のタイムスタンプを設定 # APIからデータ取得(詳細は省略) data = fetch_data(start_time) schema = infer_schema(data) return session.create_dataframe(data, schema=schema)

Slide 24

Slide 24 text

© LayerX Inc. 24 dbt.ref を使った依存関係管理 Python Modelの便利な機能と使い⽅ モデル間の参照 ● dbt.ref("other_model") を使用して、他のモデルへの依存関係を明示 利点 ● dbtが依存関係を自動解決し、正しい実行順序を保証 ● コードの保守性と再利用性が向上 参考 ● https://docs.getdbt.com/docs/build/python-models#referencing-other-models

Slide 25

Slide 25 text

⽬次 Agenda ● はじめに ● Python Modelの基礎知識 ● Python Modelの仕組み(Snowflake編) ● Python Modelの便利な機能と使い⽅ ● テストとパフォーマンスの課題 ● Snowparkライブラリに関する課題 ● Snowflake環境でのログ出⼒と重要性 ● Future Works と今後の展望

Slide 26

Slide 26 text

© LayerX Inc. 26 弊社でのテストの⽅法とアプローチ テストとパフォーマンスの課題 テストフレームワーク ● Pytest を利用 ○ ユニットテストと統合テストの両面から、 dbt Python Model の各処理(外部 API 呼び出し、データフレーム変換、フィルタ処理) の正確な動作を検証 ● モック化手法の活用 ○ monkeypatch を利用して、requests.get などの外部依存の挙動を固定のダミーデータで再現 ○ モック化により、安定した再現性の高いテスト環境を実現 テスト環境のセットアップ ● Snowflake セッションの再現 ○ Snowflake セッションを再現するためのラッパー関数( new_session())を用意 ○ 接続情報が未設定の場合は、ローカルテスト用の DummySession を使用して簡易な環境を構築

Slide 27

Slide 27 text

© LayerX Inc. 27 モデル関数 (model) の例 テストとパフォーマンスの課題 ポイント ● 外部APIからユーザーデータを取得 ● pandas.json_normalize によりネストされたデータをフラッ ト化 ● 必要なカラムのみ抽出し、 create_dataframe に渡して DataFrame を生成 def model(dbt, session): dbt.config(materialized='table', packages=['requests']) url = "https://何かサービス/users" response = requests.get(url) response.raise_for_status() data = response.json() # APIデータをフラット化して必要なカラムを抽出 df_flat = pd.json_normalize(data) data_records = df_flat[['id', 'name', 'username']].to_dict(orient="records") # Snowflake の create_dataframe はリストの辞書形式を受け⼊れる df = session.create_dataframe(data_records) return df

Slide 28

Slide 28 text

© LayerX Inc. 28 ダミーオブジェクトの定義 テストとパフォーマンスの課題 ポイント DummyDBT ● dbt.config() の呼び出しを模倣して、設定内容を出力 DummySession ● 実際の Snowflake セッションの代わりに、テスト用に pandas DataFrame を返すシンプルな実装 # ダミーの dbt オブジェクト class DummyDBT: def config(self, **kwargs): print("dbt.config called with:", kwargs) # ダミーの Session オブジェクト(テスト⽤) class DummySession: def create_dataframe(self, data): # Snowpark の create_dataframe の代わりに pandas DataFrame を返す return pd.DataFrame(data)

Slide 29

Slide 29 text

© LayerX Inc. 29 テストクラスの環境構築部分 テストとパフォーマンスの課題 ポイント ● new_session() で環境変数に応じてテスト用のダミーセッ ションまたは実際のセッションを生成 ● テスト環境に応じたセッション管理を実現 class TestDataProcessingProcedure: @contextlib.contextmanager def new_session(self): if os.environ.get('DBT_SNOWFLAKE_ACCOUNT', 'fake_account') == 'fake_account': yield DummySession() else: snowflake_account = os.environ.get('DBT_SNOWFLAKE_ACCOUNT') snowflake_user = os.environ.get('DBT_SNOWFLAKE_USER') session = Session.builder.configs({ 'account': snowflake_account, 'user': snowflake_user, … # ロールやデータベース、スキーマなどを指定する }).create() try: yield session finally: session.close()

Slide 30

Slide 30 text

© LayerX Inc. 30 外部APIモック テストとパフォーマンスの課題 ポイント ● 外部API呼び出しをモックし、固定のダミーデータを返す def fake_requests_get(self, url): # ダミーの API データを返す dummy_data = [ {"id": 1, "name": "User One", "username": "userone", "email": "[email protected]"}, {"id": 2, "name": "User Two", "username": "usertwo", "email": "[email protected]"}, {"id": 3, "name": "User Three", "username": "userthree", "email": "[email protected]"} ] class DummyResponse: def __init__(self, data): self.data = data def raise_for_status(self): pass def json(self): return self.data return DummyResponse(dummy_data)

Slide 31

Slide 31 text

© LayerX Inc. 31 テスト関数の実装 テストとパフォーマンスの課題 ポイント ● モック化した requests.get を利用して model() を実行 ● Snowpark の DataFrame を Pandas DataFrame に変換し、 カラム名を小文字化して期待値と比較 ● check_dtype=False により、dtype の違いは無視して内容の み比較 def test_model_function(self, monkeypatch): # requests.get をモック化 monkeypatch.setattr(requests, "get", self.fake_requests_get) dbt = DummyDBT() with self.new_session() as session: df = model(dbt, session) # Snowpark DataFrameの場合は toPandas() で変換 if hasattr(df, "toPandas"): df = df.toPandas() # Snowpark ではカラム名が⼤⽂字になるので⼩⽂字に変換 df.columns = [col.lower() for col in df.columns] expected = pd.DataFrame([ {"id": 1, "name": "User One", "username": "userone"}, … ]) pd.testing.assert_frame_equal(df.reset_index(drop=True), expected, check_dtype=False)

Slide 32

Slide 32 text

© LayerX Inc. 32 単体実⾏例 テストとパフォーマンスの課題 ポイント ● テストクラス外で、ダミーの dbt と new_session() を使って model() を実行 ● 結果の DataFrame をコンソールに出力し、動作確認可能 if __name__ == '__main__': dbt = DummyDBT() with TestDataProcessingProcedure().new_session() as session: result_df = model(dbt, session) print(result_df)

Slide 33

Slide 33 text

© LayerX Inc. 33 内部モジュール (_snowflake) の概要 テストとパフォーマンスの課題 専用内部モジュールとしての _snowflake ● _snowflake は、Snowflake の UDFやStreamlitなどに内部的に提供されるモジュール ● 実行中にのみ利用され、セキュアなシークレットアクセスなどの用途で使用する

Slide 34

Slide 34 text

© LayerX Inc. 34 テストにおける課題: 内部モジュール テストとパフォーマンスの課題 ローカル開発と本番環境のギャップ ● ローカル開発環境では、 _snowflake モジュールを利用する手段はない。 ● 本番環境の実行時には、専用の内部モジュールとして _snowflake が用いられており、この内部実装は秘密管理などに特化した機 能を提供する。 ○ ローカルでの挙動と本番での挙動は根本的に異なる。 モック/スタブの実装の必要性 ● 本番環境の内部モジュールの動作を再現するため、ローカルテストでは専用のモックやスタブの構築が必要な場合がある。 ● これにより、テストコードが複雑化し、保守性やデバッグが難しくなる可能性がある。

Slide 35

Slide 35 text

© LayerX Inc. 35 テストにおける課題: 環境差異の問題 テストとパフォーマンスの課題 実環境とテスト環境の違い ● 実際の Snowflake 環境とローカルテスト環境では、接続設定や権限、リソース管理などに差異があり、テスト結果に影響を与える データ型・カラム名の相違 ● Snowpark は返す DataFrame のカラム名を大文字に変換するため、テスト時に変換処理が必要となる ● データ型(例: int8 vs int64)の違いも検証を複雑にする 統合テストの再現性 ● モックやスタブで完全に実環境を再現するのは難しく、実環境での統合テストとのギャップが発生する可能性

Slide 36

Slide 36 text

© LayerX Inc. 36 パフォーマンスの課題と考慮点 テストとパフォーマンスの課題 データ処理の効率 ● インクリメンタル更新により、必要なデータのみを処理しリソースの無駄を削減 ● Snowparkを利用することで、分散処理により大規模データでも高速処理が可能 メモリ管理の課題 ● Snowflakeの分散アーキテクチャにより、全データが一度にメモリに乗らない仕組み ● ただし、データのロードやデータの処理の仕方が悪いことによりメモリリークが起こる可能性がある ログ出力とモニタリング ● 実行時ログを活用して、パフォーマンスのボトルネックやエラー発生箇所を特定 ● 定期的なパフォーマンステストにより、処理効率を継続的に評価

Slide 37

Slide 37 text

⽬次 Agenda ● はじめに ● Python Modelの基礎知識 ● Python Modelの仕組み(Snowflake編) ● Python Modelの便利な機能と使い⽅ ● テストとパフォーマンスの課題 ● Snowflake環境でのログ出⼒と重要性 ● Future Works と今後の展望

Slide 38

Slide 38 text

© LayerX Inc. 38 Snowflake のログ‧トレーシング設定 Snowflake環境でのログ出⼒と重要性 Telemetry Levels の概要 ● Snowflake では、ログ出力とトレーシングの詳細度を制御するために Telemetry Levels を設定できます。 ● 設定により、エラー情報、警告、情報レベル、デバッグ情報などの出力を調整可能。 設定方法の参考 ● 詳細は Snowflake Telemetry Levels を参照

Slide 39

Slide 39 text

© LayerX Inc. 39 ログ&トレーシングを組み込む Snowflake環境でのログ出⼒と重要性 ポイント ● logger.info で各処理段階の情報を出力 ● トレーシングで「 fetch_and_process_data」スパン内の処理 を記録し、デバッグを支援 import logging import requests from snowflake import telemetry from opentelemetry import trace logger, trace = logging.getLogger("example"), trace.get_tracer("example") def model(dbt, session): dbt.config(materialized='table', packages=['snowflake-telemetry-python', 'opentelemetry-api', 'requests']) logger.info("Model execution started") with tracer.start_as_current_span("fetch_and_process_data"): data = requests.get("https://何かサービス/users") logger.info("Data retrieved from API") … df = session.create_dataframe(data_records) logger.info("DataFrame created successfully") return df

Slide 40

Slide 40 text

© LayerX Inc. 40 Snowflake ログ出⼒ & トレーシングの重要性 Snowflake環境でのログ出⼒と重要性 運用監視・デバッグ ● リアルタイムでエラー・パフォーマンスを監視し、トラブルシューティングに役立 てる トレーシングによる処理の可視化 ● 処理の各段階(データ取得、変換、 DataFrame作成)の流れを追跡し、ボトル ネックを特定

Slide 41

Slide 41 text

⽬次 Agenda ● はじめに ● Python Modelの基礎知識 ● Python Modelの仕組み(Snowflake編) ● Python Modelの便利な機能と使い⽅ ● テストとパフォーマンスの課題 ● Snowflake環境でのログ出⼒の重要性 ● Future Works と今後の展望

Slide 42

Slide 42 text

© LayerX Inc. 42 Programmatic Invocations の活⽤ Future Works と今後の展望 概要 ● Programmatic Invocations は、dbt モデルの実行をプログラム的に制御する仕組み 自動エラーハンドリング ● モデル実行時にエラーが発生した場合、そのエラー情報を自動でキャプチャし、適切なハンドリングを実施 ● エラー発生時の自動リトライや通知、あるいはエラーをログに記録することで、迅速な対処を実現 参考 ● https://docs.getdbt.com/reference/programmatic-invocations

Slide 43

Slide 43 text

© LayerX Inc. 43 テスト‧デバッグ環境の改善 Future Works と今後の展望 現状の課題 ● 共通で利用できるテスト環境が未整備のため、各モデルごとに個別のモックやスタブ実装が必要 ● ローカルテストと本番環境の差異により、デバッグが困難な場合がある 今後の取り組み ● ユニットテスト環境の提供 ○ ローカルでのユニットテストが確実に動作するよう、共通のテストユーティリティやラッパー関数を整備し、再現性の高い環境 を構築 ○ e2e テストは dbt test で十分なため、ユニットテストの精度向上に注力する ● 共通ライブラリの整備と活用 ○ 処理をUDF やストアドプロシージャとして切り出すか、 Snowflake に Zip でパッケージ化し置くか、共通ライブラリの配置・管 理方法を検討し、全モデルで再利用できる仕組みを構築する ○ ログ出力、トレーシング、モック化のベストプラクティスを作成し、 CI/CD パイプラインに組み込むことで、環境差異の影響を最 小化

Slide 44

Slide 44 text

まとめ

Slide 45

Slide 45 text

© LayerX Inc. 45 まとめ ● dbt Python Model の全体像について紹介し、 PythonコードはAST解析を経てモデル定義に変換され、 Snowflake上で実行される仕 組みについて解説しました。 ● Pytestを用いたユニットテスト環境とモック/スタブの工夫により、環境差異への対応やデバッグを容易にする方法について紹介しま した。 ● 将来的には、Programmatic Invocationsによる自動エラーハンドリングや統一されたテスト・デバッグ環境の整備を目指しています。

Slide 46

Slide 46 text

© LayerX Inc. 46 We are hiring!! LayerXではアナリティクスエンジニア、アナリストを積極採用中です! 少しでもご興味を持たれた方は、カジュアル面談に是非いらしてください!