メインコンテンツまでスキップ

Unity CatalogのSQLとPythonユーザー定義関数 (UDF)

備考

プレビュー

この機能は パブリック プレビュー段階です。

Unity Catalog のユーザー定義関数 (UDF) は、Databricks 内で SQL および Python の機能を拡張します。複数のコンピューティング環境間で、カスタム関数を定義、使用し、安全に共有および管理できます。

Unity Catalogで関数として登録されているPython UDFは、ノートブックまたはSparkSessionにスコープ設定されたPySpark UDFとはスコープとサポートが異なります。Python スカラー ユーザー定義関数 (UDFs)を参照してください。

Unity Catalog で Scala または Java で記述された UDF を登録するには、Unity Catalog の Scala および Java ユーザー定義関数 (UDF) を参照してください。

完全な SQL 言語リファレンスについては、 CREATE FUNCTION (SQL と Python) を参照してください。

必要条件

Unity Catalog で UDF を使用するには、次の要件を満たす必要があります。

  • Pythonに登録された UDF でUnity Catalog コードを使用するには、サーバレスまたはプロSQL の ウェアハウスを使用するか、13.3Databricks Runtime LTS以降 実行しているクラスタリングを使用する必要があります。
  • ビューにUnity Catalog Python UDFが含まれている場合、従来のSQLウェアハウスでは失敗します。
  • Unity カタログ対応クラスター上の Scala UDF の ARM インスタンス サポートは、Databricks Runtime 15.2 以降で利用できます。

Unity Catalog での SQL および Python UDF の作成

Unity Catalog で SQL または Python UDF を作成するには、ユーザーはスキーマに対する USAGE および CREATE 権限、ならびにカタログに対する USAGE 権限が必要です。詳細については、Unity Catalog を参照してください。

UDF を実行するには、UDF に対する EXECUTE 権限が必要です。 ユーザーには、スキーマとカタログに対する USAGE 権限も必要です。

Unity Catalog スキーマで UDF を作成して登録するには、関数名は catalog.schema.function_name の形式に従う必要があります。または、SQL エディターで正しいカタログとスキーマを選択できます。この場合、関数名には catalog.schema を先頭に追加してはなりません:

カタログとスキーマが事前に選択された UDF を作成します。

次の例では、my_catalog カタログの my_schema スキーマに新しい関数を登録します。

SQL
CREATE OR REPLACE FUNCTION my_catalog.my_schema.calculate_bmi(weight DOUBLE, height DOUBLE)
RETURNS DOUBLE
LANGUAGE SQL
RETURN
SELECT weight / (height * height);

Unity CatalogのPython UDFは、二重ドル記号 ($$) でオフセットされたステートメントを使用します。データ型マッピングを指定する必要があります。次の例は、体格指数を計算するUDFを登録する方法を示しています:

SQL
CREATE OR REPLACE FUNCTION my_catalog.my_schema.calculate_bmi(weight_kg DOUBLE, height_m DOUBLE)
RETURNS DOUBLE
LANGUAGE PYTHON
AS $$
return weight_kg / (height_m ** 2)
$$;

これで、この Unity Catalog 関数を SQL クエリまたは PySpark コードで使用できるようになりました。

SQL
SELECT person_id, my_catalog.my_schema.calculate_bmi(weight_kg, height_m) AS bmi
FROM person_data;

UDF のその他の例については、 行フィルターの例列マスクの例 を参照してください。

カスタムの依存関係を使用した UDF の拡張

備考

プレビュー

この機能は パブリック プレビュー段階です。

サーバレス SQLウェアハウスにインターネットからカスタム依存関係をインストールするには、ワークスペースのプレビューページPublic Preview 機能「**Serverless SQL Warehouses での分離されたワークロードのネットワークを有効にする**」を有効にする必要があります。

外部ライブラリのカスタム依存関係を定義することで、Unity Catalog Python UDF の機能を Databricks Runtime 環境を超えて拡張できます。

要件

Unity Catalog UDF のカスタム依存関係は、次のコンピュートタイプでサポートされています。

  • サーバレス ノートブック and ジョブ
  • Databricks Runtimeバージョン16.2以降を使用するクラシック汎用コンピュート
  • プロまたはサーバーレスSQLウェアハウス
注記

サーバレス SQLウェアハウスは特定の CPU アーキテクチャを保証しません。ウェアハウスは aarch64 または x86_64 のいずれかで実行でき、再起動間でアーキテクチャを変更できます。Unity Catalog Python UDF は、その依存関係がビルドされたアーキテクチャとは異なるアーキテクチャで実行できるため、その依存関係は、呼び出し元のコンピュートが使用する可能性のあるすべてのアーキテクチャをサポートする必要があります。

依存関係がネイティブ (C) 拡張機能を持つ Python wheel である場合、そのプレビルドされたバイナリはアーキテクチャ固有です。1つのアーキテクチャのみ用にビルドされたホイールは、他方へのインストールに失敗し、ISOLATION_ENVIRONMENT_USER_ERROR.GENERICエラーを返します。これを避けるには、dependenciesaarch64x86_64 の両方のホイールバリアントを含め、それぞれを platform_machine環境マーカー でそのアーキテクチャに制約します。

依存関係ソース

次のソースから依存関係をインストールします。

  • PyPI パッケージ
  • Unity Catalog ボリュームに格納されたファイル UDF を呼び出すユーザーは、ソース ボリュームに対する READ VOLUME アクセス許可を持っている必要があります。
  • パブリックURLで利用可能なファイル ワークスペースのネットワークセキュリティルールは、パブリックURLへのアクセスを許可する必要があります。要件を参照してください。
注記

ワークスペースでサーバレスネットワークアクセスが制限されている場合は、パブリックURLを許可するようにネットワークセキュリティルールを構成する必要があります。出力ルールを設定するを参照してください。

依存関係を定義する

UDF 定義の ENVIRONMENT セクションを使用して、依存関係を指定します。

SQL
CREATE OR REPLACE FUNCTION my_catalog.my_schema.mixed_process(data STRING)
RETURNS STRING
LANGUAGE PYTHON
ENVIRONMENT (
dependencies = '["simplejson==3.19.3", "/Volumes/my_catalog/my_schema/my_volume/packages/custom_package-1.0.0.whl", "https://my-bucket.s3.amazonaws.com/packages/special_package-2.0.0.whl?Expires=2043167927&Signature=abcd"]',
environment_version = '3'
)
AS $$
import simplejson as json
import custom_package
return json.dumps(custom_package.process(data))
$$;

ENVIRONMENT セクションには、次のフィールドが含まれています。

フィールド

説明

タイプ

使用例

dependencies

インストールするコンマ区切りの依存関係の一覧。各エントリは、 pip Requirements File Format に準拠した文字列です。

STRING

dependencies = '["simplejson==3.19.3", "/Volumes/catalog/schema/volume/packages/my_package-1.0.0.whl"]'

dependencies = '["https://my-bucket.s3.amazonaws.com/packages/my_package-2.0.0.whl?Expires=2043167927&Signature=abcd"]'

environment_version

UDF を実行するサーバレス環境のバージョンを指定します。固定された環境バージョンは、基盤となる Databricks Runtime の Python バージョンやパッケージとは関係なく、特定の Python バージョンとプリインストールされたパッケージのセットで UDF を実行します。

サポートされる値は None または環境バージョン 3 以上です。None 以外の環境バージョンは、サーバレスコンピュートおよびサーバレス SQLウェアハウスでのみサポートされています。利用可能なバージョンの一覧については、サーバレス環境のバージョンを参照してください。

STRING

environment_version = '3'

フィールド

説明

タイプ

使用例

dependencies

インストールするコンマ区切りの依存関係の一覧。各エントリは、 pip Requirements File Format に準拠した文字列です。

STRING

dependencies = '["simplejson==3.19.3", "/Volumes/catalog/schema/volume/packages/my_package-1.0.0.whl"]'

dependencies = '["https://my-bucket.s3.amazonaws.com/packages/my_package-2.0.0.whl?Expires=2043167927&Signature=abcd"]'

environment_version

UDF を実行するサーバレス環境のバージョンを指定します。固定された環境バージョンは、基盤となる Databricks Runtime の Python バージョンやパッケージとは関係なく、特定の Python バージョンとプリインストールされたパッケージのセットで UDF を実行します。

サポートされる値は None または環境バージョン 3 以上です。None 以外の環境バージョンは、サーバレスコンピュートおよびサーバレス SQLウェアハウスでのみサポートされています。利用可能なバージョンの一覧については、サーバレス環境のバージョンを参照してください。

STRING

environment_version = '3'

PySparkでUnity Catalog UDF を使用する

Python
from pyspark.sql.functions import expr

result = df.withColumn("bmi", expr("my_catalog.my_schema.calculate_bmi(weight_kg, height_m)"))
display(result)

セッション スコープの UDF のアップグレード

注記

Unity Catalog の Python UDF の構文とセマンティクスは、SparkSession に登録されている Python UDF とは異なります。 ユーザー定義のスカラー関数 - Pythonを参照してください。

Databricks ノートブックに次のセッションベースの UDF があるとします。

Python
from pyspark.sql.functions import udf
from pyspark.sql.types import StringType

@udf(StringType())
def greet(name):
return f"Hello, {name}!"

# Using the session-based UDF
result = df.withColumn("greeting", greet("name"))
result.show()

これを Unity Catalog 関数として登録するには、次の例のように SQL CREATE FUNCTION ステートメントを使用します。

SQL
CREATE OR REPLACE FUNCTION my_catalog.my_schema.greet(name STRING)
RETURNS STRING
LANGUAGE PYTHON
AS $$
return f"Hello, {name}!"
$$

Unity Catalog で UDF を共有する

UDF を登録するカタログ、スキーマ、またはデータベースに適用されるアクセス制御によって、その権限が管理されます。詳細については、Unity Catalog での権限の管理を参照してください。

Databricks SQL または Databricks ワークスペース UI を使用して、ユーザーまたはグループにアクセス許可を付与します (推奨)。

ワークスペース UI のアクセス許可

  1. UDF が格納されているカタログとスキーマを検索し、UDF を選択します。
  2. UDF 設定で アクセス許可 オプションを探します。ユーザーまたはグループを追加し、EXECUTE や MANAGE など、付与する必要があるアクセスの種類を指定します。

ワークスペース UI の権限

Databricks SQL を使用したアクセス許可

次の例では、関数に対する EXECUTE パーミッションをユーザーに付与します。

SQL
GRANT EXECUTE ON FUNCTION my_catalog.my_schema.calculate_bmi TO `user@example.com`;

アクセス許可を削除するには、次の例のように REVOKE コマンドを使用します。

SQL
REVOKE EXECUTE ON FUNCTION my_catalog.my_schema.calculate_bmi FROM `user@example.com`;

環境分離

注記

共有分離環境には、Databricks Runtime 18.0 以上が必要です。以前のバージョンでは、すべての Unity Catalog Python UDF は厳密な分離モードで実行されます。

同じ所有者とセッションを持つUnity Catalog Pythonユーザー定義関数 (UDF) は、defaultで分離環境を共有できます。これにより、起動する必要がある個別の環境の数を減らすことで、パフォーマンスが向上し、メモリ使用量が削減されます。

厳格な隔離

UDF が常に独自の完全に隔離された環境で実行されることを検証するには、STRICT ISOLATION 特性句を追加します。

ほとんどの UDF では厳密な分離は必要ありません。標準データ処理 UDF は、デフォルトの共有分離環境の恩恵を受け、メモリ消費量を抑えながら高速に実行されます。

次の UDF にSTRICT ISOLATION特性句を追加します:

  • eval()exec() 、または同様の関数を使用して、入力をコードとして実行します。
  • ファイルをローカル ファイル システムに書き込みます。
  • グローバル変数またはシステム状態を変更します。
  • 環境変数にアクセスまたは変更します。

次のコードは、STRICT ISOLATION を使用して実行する必要がある UDF の例を示しています。この UDF は任意の Python コードを実行するため、システムの状態を変更したり、環境変数にアクセスしたり、ローカルファイルシステムに書き込んだりする可能性があります。STRICT ISOLATION 句を使用すると、UDF 間での干渉やデータ漏洩を防ぐのに役立ちます。

SQL
CREATE OR REPLACE TEMPORARY FUNCTION run_python_snippet(python_code STRING)
RETURNS STRING
LANGUAGE PYTHON
STRICT ISOLATION
AS $$
import sys
from io import StringIO

# Capture standard output and error streams
captured_output = StringIO()
captured_errors = StringIO()
sys.stdout = captured_output
sys.stderr = captured_errors

try:
# Execute the user-provided Python code in an empty namespace
exec(python_code, {})
except SyntaxError:
# Retry with escaped characters decoded (for cases like "\n")
def decode_code(raw_code):
return raw_code.encode('utf-8').decode('unicode_escape')
python_code = decode_code(python_code)
exec(python_code, {})

# Return everything printed to stdout and stderr
return captured_output.getvalue() + captured_errors.getvalue()
$$

関数が一貫した結果を生成する場合に DETERMINISTIC を設定します

同じ入力に対して同じ出力を生成する場合は、関数定義に DETERMINISTIC を追加します。これにより、クエリの最適化によりパフォーマンスが向上します。

defaultでは、明示的に宣言しない限り、Databricks はバッチ Unity Catalog Python UDF を非決定論的と見なします。非決定論的関数の例には、ランダムな値を生成する、現在の時刻や日付にアクセスする、外部 API を呼び出す、などがあります。

「CREATE FUNCTION (SQL および Python)」を参照してください。

AI エージェント ツールの UDFs

生成AIエージェントは、タスクを実行し、カスタムロジックを実行するためのツールとして Unity Catalog UDF を使用できます。

Unity Catalog 関数を使用して AI エージェント ツールを作成する」を参照してください。

外部APIにアクセスするための UDF

UDF を使用して、SQLから外部API にアクセスできます。次の例では、Python requests ライブラリを使用して HTTP リクエストを行います。

注記

Python UDF は、サーバレス コンピュートまたは標準アクセス モードで構成されたコンピュートを使用する場合、ポート 80、443、および 53 を介した TCP/UDP ネットワーク トラフィックを許可します。

SQL
CREATE FUNCTION my_catalog.my_schema.get_food_calories(food_name STRING)
RETURNS DOUBLE
LANGUAGE PYTHON
AS $$
import requests

api_url = f"https://example-food-api.com/nutrition?food={food_name}"
response = requests.get(api_url)

if response.status_code == 200:
data = response.json()
# Assume the API returns a JSON object with a 'calories' field
calories = data.get('calories', 0)
return calories
else:
return None # API request failed

$$;

セキュリティとコンプライアンスのための UDF

Python UDF を使用して、カスタムトークン化、データマスキング、データ編集、または暗号化メカニズムを実装します。

次の例では、Eメール アドレスの ID をマスクしながら、長さとドメインを維持します。

SQL
CREATE OR REPLACE FUNCTION my_catalog.my_schema.mask_email(email STRING)
RETURNS STRING
LANGUAGE PYTHON
DETERMINISTIC
AS $$
parts = email.split('@', 1)
if len(parts) == 2:
username, domain = parts
else:
return None
masked_username = username[0] + '*' * (len(username) - 2) + username[-1]
return f"{masked_username}@{domain}"
$$

次の例では、この UDF を動的ビュー定義に適用します。

SQL
-- First, create the view
CREATE OR REPLACE VIEW my_catalog.my_schema.masked_customer_view AS
SELECT
id,
name,
my_catalog.my_schema.mask_email(email) AS masked_email
FROM my_catalog.my_schema.customer_data;

-- Now you can query the view
SELECT * FROM my_catalog.my_schema.masked_customer_view;
+---+------------+------------------------+------------------------+
| id| name| email| masked_email |
+---+------------+------------------------+------------------------+
| 1| John Doe| john.doe@example.com | j*******e@example.com |
| 2| Alice Smith|alice.smith@company.com |a**********h@company.com|
| 3| Bob Jones| bob.jones@email.org | b********s@email.org |
+---+------------+------------------------+------------------------+

ベストプラクティス

すべてのユーザーが UDF にアクセスできるようにするために、Databricks では、適切なアクセス制御を備えた専用のカタログとスキーマを作成することをお勧めします。

チーム固有の UDF の場合は、チーム カタログ内の専用スキーマを使用して、ストレージと管理を行います。

Databricks では、UDF ドキュメント文字列に次の情報を含めることをお勧めします。

  • 現在のバージョン番号
  • バージョン間での変更を追跡するための変更ログ
  • UDF の目的、パラメーター、および戻り値
  • UDF の使用方法の例

次の例は、ベストプラクティスに従ったUDFを示しています。

SQL
CREATE OR REPLACE FUNCTION my_catalog.my_schema.calculate_bmi(weight_kg DOUBLE, height_m DOUBLE)
RETURNS DOUBLE
COMMENT "Calculates Body Mass Index (BMI) from weight and height."
LANGUAGE PYTHON
DETERMINISTIC
AS $$
"""
Parameters:
calculate_bmi (version 1.2):
- weight_kg (float): Weight of the individual in kilograms.
- height_m (float): Height of the individual in meters.

Returns:
- float: The calculated BMI.

Example Usage:

SELECT calculate_bmi(weight, height) AS bmi FROM person_data;

Change Log:
- 1.0: Initial version.
- 1.1: Improved error handling for zero or negative height values.
- 1.2: Optimized calculation for performance.

Note: BMI is calculated as weight in kilograms divided by the square of height in meters.
"""
if height_m <= 0:
return None # Avoid division by zero and ensure height is positive
return weight_kg / (height_m ** 2)
$$;

入力時のタイムスタンプタイムゾーンの動作

Databricks Runtime 18.0 以上では、TIMESTAMP 値を Python UDF に渡すと、値は UTC のままになります。ただし、datetime オブジェクトにはタイムゾーン メタデータ(tzinfo 属性)は含まれていません。

この変更により、Unity Catalog Python UDF が Apache Spark の Arrow に最適化された Python UDF と整合されます。

たとえば、次のクエリ:

SQL
CREATE FUNCTION timezone_udf(date TIMESTAMP)
RETURNS STRING
LANGUAGE PYTHON
AS $$
return f"{type(date)} {date} {date.tzinfo}"
$$;

SELECT timezone_udf(TIMESTAMP '2024-10-23 10:30:00');

以前は、18.0 より前のバージョンの Databricks Runtime でこの出力が生成されていました。

<class 'datetime.datetime'> 2024-10-23 10:30:00+00:00 Etc/UTC

Databricks Runtime 18.0 以降では、次の出力が生成されるようになりました。

<class 'datetime.datetime'> 2024-10-23 10:30:00+00:00 None

UDFがタイムゾーンの情報に依存する場合、明示的に復元する必要があります。

Python
from datetime import timezone

date = date.replace(tzinfo=timezone.utc)

制限

  • Python UDF 内では任意の数の Python 関数を定義できますが、すべてがスカラー値を返す必要があります。
  • Python 関数は NULL 値を個別に処理する必要があり、すべての型マッピングは Databricks SQL 言語マッピングに従う必要があります。
  • カタログまたはスキーマを指定しない場合、Databricks は Python UDF を現在アクティブなスキーマに登録します。
  • Python UDF は、安全で隔離された環境で実行され、ファイルシステムや内部サービスにアクセスできません。
  • クエリごとに 5 つを超える UDF を呼び出すことはできません。