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

プレビュー

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

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

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

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

要件

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

  • Unity Catalog に登録されている UDF で Python コードを使用するには、サーバーレスまたは pro SQL ウェアハウス、あるいはDatabricks Runtime 13.3 LTS 以上を実行しているクラスターを使用する必要があります。

  • ビューに UC Python UDFが含まれている場合、 SQL Classic ウェアハウスでは失敗します。

  • 有効なクラスターでの Scala UDF の Graviton インスタンス サポートは、Databricks Runtime 15.2 以降で使用できます。

Unity Catalog での UDF の作成

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

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

次の例では、新しい関数を my_schema Unity Catalog スキーマに登録します。

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

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

CREATE 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 コードで使用できるようになりました。

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

PySpark での Unity Catalog UDF の使用

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 があるとします。

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 ステートメントを使用します。

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

Unity Catalog で UDF を共有する

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

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

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

  1. UDF が格納されているカタログとスキーマを検索し、UDF を選択します。

  2. UDF 設定で [アクセス許可 ] オプションを探します。 ユーザーまたはグループを追加し、EXECUTE や MANAGE など、必要なアクセスのタイプを指定します。

ワークスペース UI の権限

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

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

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

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

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

UDF のベスト プラクティス

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

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

Databricks では、UDF の docstring に次の情報を含めることをお勧めします。

  • 現在のバージョン番号

  • バージョン間での変更を追跡するための変更ログ

  • UDF の目的、パラメーター、および戻り値

  • UDF の使用方法の例

以下は、ベストプラクティスに従った UDF の例です。

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
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)
$$;

外部APIs にアクセスするための UDFs

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

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

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()
   # Assuming 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 UDFs を使用して、カスタムトークン化、データマスキング、データ編集、または暗号化メカニズムを実装します。

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

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

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

-- 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 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 |
+---+------------+------------------------+------------------------+

制限事項

  • Python UDF 内では任意の数の Python 関数を定義できますが、すべてがスカラー値を返す必要があります。

  • Python 関数は NULL 値を個別に処理する必要があり、すべての型マッピングは Databricks SQL 言語マッピングに従う必要があります。

  • Databricks に含まれる標準の Python ライブラリをインポートすることはできますが、カスタム ライブラリや外部依存関係を含めることはできません。

  • カタログまたはスキーマが指定されていない場合、Python UDF は現在アクティブなスキーマに登録されます。

  • Python UDF は安全で分離された環境で実行され、ファイルシステムや内部サービスにアクセスできません。