Python UDF ハンドラーの例¶
このトピックには、Pythonで記述された UDF ハンドラーコードの簡単な例が含まれています。
Pythonを使用して UDF ハンドラーを作成する方法については、 Python UDFsの作成 をご参照ください。
runtime_version をコードに必要なPythonランタイムのバージョンに設定します。サポートされているPythonのバージョンは次のとおりです。
一般公開されているバージョン:
3.9(非推奨)
3.10
3.11
3.12
3.13
インラインハンドラーでのパッケージのインポート¶
Anacondaのサードパーティパッケージの厳選されたリストが利用可能です。詳細については、 サードパーティパッケージの使用 をご参照ください。
注釈
Anacondaが提供するパッケージを使用する前に、Snowflake組織管理者はSnowflake 外部オファリング利用規約 に同意する必要があります。詳細については、 Anacondaのサードパーティパッケージの使用 をご参照ください。
次のコードは、パッケージをインポートしてそのバージョンを返す方法を示しています。
UDF を作成します。
UDF を呼び出します。
PACKAGES キーワードは、以下のようにパッケージのバージョンを指定するために使用できます。
バージョンなし(例:
numpy)正確なバージョンをピン留め(例:
numpy==1.25.2)ワイルドカードを使用したバージョンプレフィックスへの制約(例:
numpy==1.*)バージョン範囲への制約(例:
numpy>=1.25)複数のバージョン指定子(例:
numpy>=1.25,<2)によって制約され、すべてのバージョン指定子を満たすパッケージが選択されるようにします。
注釈
複数の範囲演算子(例: numpy>=1.25,<2)の使用はパッケージポリシーではサポートされていませんが、Python UDF、 UDTF、およびストアドプロシージャを作成する際には使用できます。
以下は、ワイルドカード * を使用してパッケージをバージョンプレフィックスに制約する例です。
この例では、パッケージが指定されたバージョン以上であることを制約する方法を示します。
次の例は、複数のパッケージバージョン指定子の使用方法を示しています。
ファイルの読み取り¶
Python UDF ハンドラーコードを使用してファイルのコンテンツを読み取ることができます。たとえば、ファイルを読み取って、非構造化データを処理する場合があります。
ファイルのコンテンツを読み取るには、
IMPORTS 句でファイルのパスと名前を静的に指定 し、ファイルを UDF のホームディレクトリから読み取ります。これは、ファイル名が静的で、関数内で一貫性があり、あらかじめファイル名がわかっている場合に有効です。
SnowflakeFile でファイルを動的に指定し、そのコンテンツを読み取ります。計算中にファイルにアクセスする必要があるときは、このような操作を実行できる場合があります。
IMPORTS を使用した静的に指定されたファイルの読み取り¶
CREATE FUNCTION コマンドの IMPORTS 句にファイル名とステージ名を指定することで、ファイルを読み込めます。
IMPORTS 句でファイルを指定すると、Snowflakeはそのファイルをステージから UDF の ホームディレクトリ (別称 インポートディレクトリ)にコピーします。UDF は、ホームディレクトリからファイルを読み取ります。
Snowflakeは、インポートしたファイルを単一のディレクトリにコピーします。そのディレクトリにあるすべてのファイルは一意な名前でなければならないため、 IMPORTS 句の各ファイルも個別の名前にする必要があります。これは、ステージングされたファイルが異なるステージや、ステージ内の異なるサブディレクトリで開始された場合でも同様です。
注釈
ファイルはステージのトップレベルディレクトリからのみインポートでき、サブフォルダからはインポートできません。
次の例では、 my_stage という名前のステージから file.txt と呼ばれるファイルを読み取るインラインPythonハンドラーを使用しています。ハンドラーは、Python sys._xoptions メソッドと snowflake_import_directory システムオプションを使用して、 UDF のホームディレクトリの位置を取得することができます。
Snowflakeは UDF の作成中に1回だけファイルを読み取り、ファイルの読み取りがターゲットハンドラーの外部で発生した場合は、 UDF の実行中にファイルを再度読み取ることはありません。
インラインハンドラーを使用して UDF を作成します。
SnowflakeFile を使用した動的に指定されたファイルの読み取り¶
Snowpark snowflake.snowpark.files モジュールの SnowflakeFile クラスを使用すると、ステージからファイルを読み取ることができます。SnowflakeFile クラスは、動的なファイルアクセスを提供し、あらゆるサイズのファイルをストリーミングすることができます。動的なファイルアクセスは、複数のファイルを反復処理する場合にも有効です。例については、 複数ファイルの処理 をご参照ください。
SnowflakeFile クラスには、ファイルを開くためのメソッド、 open があります。open メソッドは、Pythonの IOBase ファイルオブジェクトを拡張する SnowflakeFile オブジェクトを返します。
SnowflakeFile オブジェクトは、以下の IOBase、 BufferedIOBase、 RawIOBase のメソッドをサポートしています。
IOBase.fileno
IOBase.isatty
IOBase.readable
IOBase.readinto
IOBase.readline
IOBase.readlines
IOBase.seek
IOBase.seekable
IOBase.tell
BufferedIOBase.readinto1
RawIOBase.read
RawIOBase.readall
詳細については、 IOBase でのPython 3.12ドキュメント をご参照ください。メソッド fileno など、Snowflakeサーバーでサポートされていないメソッドを呼び出すと、エラーが返されます。
注釈
ファイルインジェクション攻撃に対して耐久性のあるコードにするため、 SnowflakeFile を使用したファイルアクセスには、デフォルトでスコープ付き URLs が必要です。組み込み関数 BUILD_SCOPED_FILE_URL を使用して、スコープ URL を SQL に作成できます。スコープ付き URLs の詳細については、 ファイルにアクセスできる URLs の型 をご参照ください。ファイルにアクセスできるユーザーのみが、スコープ付き URL を作成できます。
このセクションの例では、 SnowflakeFile を使用し、指定したステージの場所から1つまたは複数のファイルを読み取ります。
前提条件¶
ファイルをコードで使用できるようにするには、Pythonハンドラーコードがステージ上のファイルを読み取る前に、次を実行する必要があります。
ハンドラーが使用可能なステージを作成します。
外部ステージまたは内部ステージを使用できます。内部ステージを使用する場合、呼び出し元権限のストアドプロシージャを作成する予定であれば、これをユーザーステージにすることができます。それ以外の場合は、名前付きステージを使用する必要があります。Snowflakeは現在、UDF 依存関係のためにテーブルステージを使用してハンドラーコードを格納することはサポートしていません。
ステージの作成の詳細については、 CREATE STAGE をご参照ください。内部ステージ型の選択の詳細については、 ローカルファイルに対する内部ステージの選択 をご参照ください。
ユースケースに応じて、ステージに対する適切な権限を以下のロールに割り当てる必要があります。
ユースケース
ロール
UDF または所有者権限ストアドプロシージャ
実行中の UDF またはストアドプロシージャを所有するロール。
呼び出し元権限ストアドプロシージャ
ユーザーロール。
詳細については、 ユーザー定義関数の権限付与 をご参照ください。
コードが読み取るファイルをステージにコピーします。
PUT コマンドを使用して、ローカルドライブから内部ステージにファイルをコピーできます。PUT を使用したファイルのステージングについては、 ローカルファイルシステムからのデータファイルのステージング をご参照ください。
クラウドストレージサービスが提供するツールを使用して、ローカルドライブから外部ステージの場所にファイルをコピーできます。ヘルプについては、ご使用のクラウドストレージサービスのドキュメントをご参照ください。
インラインPythonハンドラーを使用した画像の知覚ハッシュの算出¶
この例では、 SnowflakeFile を使用して、一対のステージングされた画像ファイルを読み取り、 知覚ハッシュ (pHash)を使用して、各ファイルの画像の類似性を判定します。
mode の引数に rb を渡して入力モードをバイナリに指定し、画像のphash値を返す UDF を作成します。
2つの画像のphash値間における距離を計算する2番目の UDF を作成します。
画像ファイルをステージし、ディレクトリテーブルを更新します。
UDFs を呼び出します。
UDTF を使用した CSV ファイルの処理¶
この例では、 SnowflakeFile を使って、 CSV ファイルの内容を抽出し、その行をテーブルにして返す UDTF を作成します。
インラインハンドラーを使用して UDTF を作成します。
CSV ファイルをステージし、ディレクトリテーブルを更新します。
UDTF を呼び出し、ファイル URL を渡します。
複数ファイルの処理¶
ディレクトリテーブルの RELATIVE_PATH 列をハンドラーに渡すと、複数のファイルを読み取って処理することができます。RELATIVE_PATH 列の詳細については、 ディレクトリテーブルのクエリからの出力 をご参照ください。
注釈
ファイルサイズや計算の必要性に応じて、複数のファイルを読み取って処理するステートメントを実行する前に、 ALTER WAREHOUSE を使用してウェアハウスをスケールアップするとよいでしょう。
- UDF を呼び出して、複数のファイルを処理します。
次の例では、 CREATE TABLE ステートメント内で UDF を呼び出し、ステージ上の各ファイルを処理し、その結果を新しいテーブルに格納します。
デモのために、例では以下のように想定しています。
my_stageという名前のステージには、複数のテキストファイルがあります。非構造化テキストに対して感情分析を行う、
get_sentimentという名前の既存の UDF があります。UDF は、テキストファイルへのパスを入力とし、感情を表す値を返します。
- UDTF を呼び出して、複数のファイルを処理します。
次の例では、 UDTF という名前の
parse_excel_udtfを呼び出します。この例では、ディレクトリテーブルからrelative_pathをmy_excel_stageというステージに渡します。
ステージ URLs および URIs ハンドラーを使用したファイルの読み取り¶
SnowflakeFile を使用したファイルアクセスには、デフォルトでスコープ付き URLs が必要です。これにより、ファイルインジェクション攻撃に対して耐久性のあるコードになります。ただし、代わりにステージ URI、またはステージ URL を使用してファイルの場所を参照することはできます。そのためには、キーワード引数 require_scoped_url = False を使用して、 SnowflakeFile.open メソッドを呼び出す必要があります。
このオプションは、 UDF 所有者のみがアクセスできる URI を呼び出し元が提供できるようにする場合に便利です。たとえば、 UDF を所有していて、構成ファイルや機械学習モデルを読み取る場合、ファイルアクセスにステージ URI を使用することがあります。ユーザーの入力に基づいて作成されるファイルなど、予測不可能な名前を持つファイルを扱う場合は、このオプションを推奨しません。
この例では、機械学習モデルをファイルから読み取り、そのモデルを関数で使用して、感情分析のための自然言語処理を実行します。この例では、 open を require_scoped_url = False で呼び出します。ファイルの場所の形式両方(ステージ URI とステージ URL)で、 UDF 所有者はモデルファイルにアクセスできる必要があります。
インラインハンドラーを使用して UDF を作成します。
モデルファイルをステージし、ディレクトリテーブルを更新します。
また、 UDF にモデルのステージ URL を指定して、感情をを抽出することもできます。
たとえば、ステージ URL を使用して、ファイルを指定するインラインハンドラー付き UDF を作成します。
入力されたデータで UDF を呼び出します。
ファイルの記述¶
UDF ハンドラーは、 UDF を呼び出すクエリ用に作成された /tmp ディレクトリにファイルを書き込むことができます。
/tmp ディレクトリは単一の呼び出しクエリ用に確保されていますが、複数のPythonワーカープロセスが同時に実行されている可能性があることに注意してください。競合を防ぐには、/tmpディレクトリへのアクセスが他のPythonワーカープロセスと同期されていること、または/tmpに書き込まれるファイルの名前が一意であることを確認する必要があります。
コード例については、このトピックの ステージングされたファイルの解凍 をご参照ください。
次の例のコードは、入力された text を /tmp ディレクトリに書き込みます。また、ファイルの場所の一意性を確保するために、関数のプロセス ID を追加します。
ファイルの書き込みに関する情報については、 Snowpark Python UDFs および UDTFs からのファイルの書き込み を参照してください。
ステージングされたファイルの解凍¶
.zipファイルをステージに保存し、Python zipfileモジュールを使用してUDFで解凍できます。
たとえば、.zipファイルをステージにアップロードし、UDFを作成するときに、IMPORTS句のステージングされた場所で.zipファイルを参照できます。実行時に、Snowflakeはステージングされたファイルを、コードがアクセスできるインポートディレクトリにコピーします。
ファイルの読み取りと書き込みの詳細については、 ファイルの読み取り および ファイルの記述 をご参照ください。
次の例では、UDFコードはNLPモデルを使用してテキスト内のエンティティを検出します。コードはこれらのエンティティの配列を返します。テキストを処理するためのNLPモデルを設定するには、コードは最初にzipfileモジュールを使用して、.zipファイルからモデルのファイル(en_core_web_sm-2.3.1)を抽出します。次に、コードはspaCyモジュールを使用して、ファイルからモデルをロードします。
このコードは、抽出されたファイルの内容を、この関数を呼び出すクエリ用に作成された/tmpディレクトリに書き込むことに注意してください。このコードはファイルロックを使用して、Pythonワーカープロセス間で抽出が同期されるようにします。このようにして、コンテンツは1回だけ解凍されます。ファイルの書き込みの詳細については、 ファイルの記述 をご参照ください。
zipfileモジュールの詳細については、 zipfileリファレンス をご参照ください。spaCyモジュールの詳細については、 spaCyAPIのドキュメント をご参照ください。
インラインハンドラーを使用して UDF を作成します。
NULL 値の取り扱い¶
次のコードは、NULL値の処理方法を示しています。詳細については、 NULL 値 をご参照ください。
UDF を作成します。
UDF を呼び出します。