【要約】Snowflake Python の UDF/UDTF で ModuleNotFoundError が出る [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
SnowflakeでPythonを用いたデータ処理を行う開発者が、UDFやUDTFの定義時に予期せぬインポートエラーに直面する。具体的には、以下の状況で問題が発生する。
- ・エラー内容:
ModuleNotFoundError: No module named 'main_module'が発生する。 - ・発生条件: UDFが、同じスクリプト内のグローバルなオブジェクトに依存している場合。
- ・対象機能: Python Worksheet、Stored Procedure、dbt Python modelなど。
- ・根本原因: Snowparkの内部ロジックが、グローバルオブジェクトのモジュール名を誤認するため。
// Approach
開発者は、Snowparkの内部的なインポート判定ロジックを回避するために、以下の3つの手法を選択できる。
1.スコープの変更による回避
- ・依存オブジェクトをグローバルではなく、関数内のローカル変数として定義する。
- ・これにより、インポート追加の対象となるグローバルオブジェクトを排除する。
2.外部モジュール化による回避
- ・依存オブジェクトを別モジュールに定義し、
session.add_importでインポートする。 - ・正しいモジュール名に基づいたインポートが行われるようになる。
3.属性の書き換えによる回避
- ・オブジェクトの
__module__属性を'__main__'に手動で上書きする。 - ・モジュール名の不一致を解消し、不要なインポートを防ぐ。
// Result
これらの回避策を適用することで、開発者はSnowparkの内部実装に起因するエラーを回避できる。具体的な成果は以下の通りである。
- ・エラーの解消:
ModuleNotFoundErrorを発生させずにUDF/UDTFを実行可能にする。 - ・設計の適正化: 依存関係を明示的に管理することで、コードの堅牢性を高める。
- ・運用継続性: ライブラリ側の修正を待たずに、現行の環境で開発を継続できる。
Senior Engineer Insight
> 本件はSnowparkの内部実装に起因する挙動であり、実質的なバグである。現場のエンジニアは、ライブラリの挙動を過信せず、以下の設計指針を持つべきだ。
- ・グローバル変数の使用を極力避ける。
- ・依存関係は可能な限り明示的なインポート(外部モジュール化)で行う。