Unity カタログの SQL および Python ユーザー定義関数 (UDF)

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

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

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

UnityカタログでどのワークロードやテーブルがUDFを参照しているかを修正する前に確認するには、「 View UDF lineage」をご覧ください。

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

必要条件

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

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

スカラーおよびバッチUnityカタログのPython UDFは、一般的にすべての対応計算タイプで利用可能です。

Python UDFの機能要件

要件は特徴によって異なります。 Databricks Runtime 19および環境バージョン6は、Unity Catalog Python UDFの一般的な要件ではありません。

サーバーレスノートブックやジョブ上のPySparkセッションUDFの場合、環境要件はセッション環境を指します。 SQLで定義されたPython UDFは、各関数のENVIRONMENT節でenvironment_versionを参照します。 セッション環境を変更しても、既存のUnity Catalog関数の環境は変わりません。 例えば、環境バージョン6を使用するセッションは、環境バージョン5で定義されたUnityカタログ関数を呼び出すことができます。

特徴 必要条件
ENVIRONMENT 句とカスタム依存関係 サーバーレス ノートブックとジョブ、プロ版またはサーバーレス SQL ウェアハウス、クラシック コンピューティング上の Databricks Runtime 16.2 以降。 Databricks Runtime 16.2 から 18.1 を実行しているクラシック ・コンピューティングでは、environment_version は 'None' でなければなりません。
バッチ Unity Catalog Python UDF サーバーレス計算;プロおよびサーバーレスSQLウェアハウス;Databricks Runtime 16.3以上をクラシックコンピュートで支援
スカラーPython UDFの名付けハンドラー Databricks Runtime 18.1以上をクラシックコンピュートで搭載しています。 サーバーレスコンピュートやプロ・サーバーレスのSQLウェアハウスでは、UDFの environment_version を明示的に 6 以上に設定してください。
スカラーPython UDFにおけるサービス認証情報 Databricks Runtime 18.1以上をクラシックコンピュートで搭載しています。 サーバーレスコンピュートやプロ・サーバーレスのSQLウェアハウスでは、UDFの environment_version を明示的に 6 以上に設定してください。 クラシックコンピュートは環境バージョン6を必要としません。 サーバーレスSQLウェアハウスでは、隔離ワークロードのネットワーク機能であるPublic Previewも有効にしてください。
Unity Catalog のバッチ Python UDF におけるサービス資格情報 サーバーレス計算;プロおよびサーバーレスSQLウェアハウス;Databricks Runtime 16.3以上をクラシックコンピュートで支援。 環境バージョン6は必須ではありません。 サーバーレスSQLウェアハウスでは、隔離ワークロードのネットワーク機能であるPublic Previewも有効にしてください。
スカラーまたはバッチの Unity Catalog Python UDF でのシークレット environment_version を明示的に 6 以上に設定する; サーバーレス コンピュート; Pro およびサーバーレス SQL ウェアハウス; クラシック コンピュートで標準アクセス モードを使用する Databricks Runtime 19 以上。 専用アクセスモードの計算では直接呼び出しはサポートされていません。
PySpark互換 TIMESTAMP 入力挙動 Databricks Runtime 18.1以上をクラシックコンピュートで搭載しています。 サーバーレスコンピュートやプロ・サーバーレスのSQLウェアハウスでは、UDFの environment_version を明示的に 6 以上に設定してください。
1つのクエリ内での5回を超えるUDFの呼び出し Databricks Runtime 18.1以上をクラシックコンピュートで搭載しています。 サーバーレスコンピュートやプロ・サーバーレスのSQLウェアハウスでは、各UDFの environment_version を明示的に 6 以上に設定してください。

パブリックプレビュー時に利用可能だった既存のUDFや機能は、該当する以前のランタイムバージョンで引き続き動作します。

環境バージョンはまた、呼び出し者がUnityカタログボリュームに保存された依存関係に直接アクセスする必要があるかどうかも決定します。 Unityカタログボリュームの依存関係に関する権限を参照してください。

クラシックコンピュート上の環境バージョン

従来のコンピューティング環境では、environment_version を 'None' 以外の値に設定するには、Databricks Runtime 18.2 以降が必要です。 Databricks Runtime 16.2 から 18.1 では、ENVIRONMENT句を使用する場合は常に environment_version = 'None' を設定してください。 'None' という値は、Python のデフォルト環境を使用します。

Databricks Runtime 18.2 以降では、動作を予測可能にするため、Azure Databricks では、各 Unity Catalog Python UDF 定義において、明示的に固定値 environment_version を設定することを推奨しています。 UDF の機能要件を満たし、以下の互換性に関する推奨事項に従ったバージョンを選択してください:

Databricks Runtime のバージョン 推奨環境の最大バージョン
18.2 から 18.x まで 5
19.x 6

Unity カタログでの SQL UDF とPython UDF の作成

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

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

Unity カタログ スキーマに UDF を作成して登録するには、関数名が catalog.schema.function_name形式に従っている必要があります。 または、SQL エディターで適切なカタログとスキーマを選択することもできます。 この場合、関数名の前に catalog.schema を付けてはなりません。

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

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

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

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

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

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

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

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

スカラーPython UDFで名前付きハンドラーを使いましょう

クラシックコンピュートでは、名前付きハンドラーはDatabricks Runtime 18.1以上が必要です。 サーバーレスコンピュートやプロ・サーバーレスのSQLウェアハウスでは、UDFの environment_version を明示的に 6 以上に設定してください。 たとえば、次の例では、環境バージョン 6 を使用しています。 Databricks Runtime 18.1 を実行しているクラシック コンピューティングでは、ENVIRONMENT 句を省略してください。 新しいランタイム バージョンでは、この句を含める場合は、互換性に関する推奨事項に従ってください。

HANDLER節を使って、UDF本体のPython関数をエントリポイントとして名付けます。 名前付きハンドラーはUDF引数を受け取り、宣言された返り値に一致する値を返します。 ハンドラーの外部のコードは、各Python環境がUDFを初期化する際に実行され、ハンドラが入力を処理する前に動作します。 このコードはハンドラコール間で再利用可能な一回限りの初期化に使えます。

以下の例では、UDF入力を処理する関数greet_handlerを定義する前にgreeting_prefixを初期化します。

CREATE OR REPLACE FUNCTION my_catalog.my_schema.greet(name STRING)
RETURNS STRING
LANGUAGE PYTHON
HANDLER 'greet_handler'
ENVIRONMENT (
  environment_version = '6'
)
AS $$
# Runs once when each Python environment initializes the UDF.
greeting_prefix = "Hello"

def greet_handler(name):
    return f"{greeting_prefix}, {name}!"
$$;

Python UDFで秘密を使う

スカラーおよびバッチの Unity Catalog Python UDF は、SECRETS 句で宣言されたシークレットにアクセスできます。 UDFの定義は明示的に environment_version を 6 以上に設定しなければなりません。 Unity Catalogのシークレットは3つの部分からなる名前(catalog.schema.secret)を使用し、ワークスペースレベルのAzure Databricksシークレットとは異なります。 計算サポート、権限、専用計算カラムマスク例外については、 UDFの要件と権限を参照してください。

UDF からシークレットを取得するには:

  1. UDF定義の「 SECRETS 」節に秘密の3つの部分名を追加します。 UDFはこの節で宣言された秘密のみを取得できます。
  2. UDF本体でカタログ、スキーマ、秘密名を databricks.secrets.get() 呼び出します。

以下のスカラーUDFの例は、Unity Catalogの秘密をハッシュベースのメッセージ認証コード(HMAC)署名鍵として使用しています。 同じ SECRETS 節を PARAMETER STYLE PANDAS に使い、バッチ UDF ハンドラから宣言された秘密にアクセスします。

CREATE OR REPLACE FUNCTION main.default.sign_value(value STRING)
RETURNS STRING
LANGUAGE PYTHON
SECRETS (main.default.hmac_key)
ENVIRONMENT (
  environment_version = '6'
)
AS $$
import hashlib
import hmac
from databricks.secrets import get

key = get(catalog="main", schema="default", key="hmac_key")
return hmac.new(key.encode(), value.encode(), hashlib.sha256).hexdigest()
$$;

Warning

UDFからシークレット値を返さないでください。 秘密の黒塗りはエラーやログでの偶発的な露出を減らすのに役立ちますが、UDFコードがクエリ結果に秘密資料を露出させるのを防ぐものではありません。

カスタム依存関係を使用して UDF を拡張する

メモ

サーバーレス SQL ウェアハウスにインターネットからカスタム依存関係をインストールするには、ワークスペースの [プレビュー] ページ で、サーバーレス SQL Warehouse で分離されたワークロードのネットワークを有効にする パブリック プレビュー機能が有効になっている必要があります。

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

要件

Unity カタログ UDF のカスタム依存関係は、次のコンピューティングの種類でサポートされています。

  • サーバーレス ノートブックとジョブ
  • Databricks Runtime バージョン 16.2 以降を使用した従来の汎用コンピューティング
  • Pro またはサーバーレス SQL ウェアハウス

依存関係ソース

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

  • PyPI パッケージ
  • Unityカタログボリュームに保存されるファイルUnityカタログボリュームの依存関係に関する権限を参照してください。
  • パブリック URL で使用できるファイル ワークスペース のネットワーク セキュリティ規則では、パブリック URL へのアクセスを許可する必要があります。 要件を参照してください。

メモ

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

Unity Catalogボリュームにおける依存関係の権限

そのボリュームから UDF への依存関係を追加するには、関数の作成者がソース ボリューム上の READ VOLUME を持っている必要があります。

定義が明示的に environment_version を 6 以上に設定しているUDFの場合、呼び出し者はUDF上で EXECUTE が必要ですが、ソースボリュームで READ VOLUME する必要はありません。 UDFの定義が environment_versionを省略したり、 Noneに設定したり、以前のバージョンに設定した場合、呼び出し側はソースボリュームにも READ VOLUME を持っている必要があります。

依存関係の定義

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

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 = '6'
)
AS $$
import simplejson as json
import custom_package
return json.dumps(custom_package.process(data))
$$;

ENVIRONMENT セクションには、次のフィールドがあります。

フィールド 説明 タイプ 使用例
dependencies インストールするコンマ区切りの依存関係の一覧。 各エントリは、 pip Requirements ファイル形式に準拠する文字列です。 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を実行する環境バージョンを指定します。 このフィールドは、 ENVIRONMENT 節が存在する場合に必ず必要となります。 固定環境バージョンでは、基になる Databricks ランタイムのPythonバージョンとパッケージに関係なく、特定のPython バージョンとプレインストール済みパッケージのセットで UDF が実行されます。
サポートされる値は、環境バージョンが3以上、例えば '6'や文字列 'None'です。 'None'値はデフォルトのPython環境を選択します。 従来のコンピューティング環境では、environment_version を 'None' 以外の値に設定するには、Databricks Runtime 18.2 以降が必要です。 Databricks Runtime 16.2 から 18.1 までは、'None' のみがサポートされています。 特定の環境バージョンがサポートされている場合は、動作を予測できるように、明示的にそのバージョンを選択してください。
サーバーレスコンピュートやプロ・サーバーレスSQLウェアハウスでは、一部の機能が環境バージョンを明示的に要求します。 各UDF定義で environment_version を必要なバージョン以上に設定してください。 その ENVIRONMENT 条項全体や設定 environment_version = 'None' を省略しても、それらの機能は有効になりません。 Python UDFの機能要件を参照してください。
クラシック コンピューティングの互換性については、クラシック コンピューティングの環境バージョンを参照してください。 利用可能なバージョンの一覧については、 環境バージョンをご覧ください。
STRING environment_version = '6'

PySpark で Unity カタログ 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 を参照してください。

Azure 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 カタログ関数として登録するには、次の例のように SQL CREATE FUNCTION ステートメントを使用します。

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

Unity カタログで UDF を共有する

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

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

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

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

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

Azure 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`;

環境の分離

メモ

共有隔離環境にはDatabricks Runtime 18.1以降が必要です。 以前のバージョンでは、すべての Unity カタログ Python UDF が厳密分離モードで実行されます。

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

厳密な分離

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

ほとんどの UDF では、厳密な分離は必要ありません。 標準のデータ処理 UDF は、既定の共有分離環境の利点を活用し、メモリ消費量が少ないほど高速に実行できます。

次のSTRICT ISOLATION特性句を次の条件を満たす UDF に追加します。

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

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

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 を追加します。 これにより、クエリの最適化によってパフォーマンスが向上します。

既定では、Azure Databricksは明示的に宣言しない限り、Batch Unity カタログPython UDF を非決定的として扱います。 非決定論的関数の例としては、ランダムな値の生成、現在の時刻や日付へのアクセス、外部 API 呼び出しなどがあります。

CREATE FUNCTION (SQL、Python、Scala、Java) を参照してください

エージェント用ツールの UDF

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

Unity カタログ関数を使用したエージェント ツールの作成を参照してください。

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

UDF を使用して、SQL から外部 API にアクセスできます。 次の例では、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()
   # 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 を使用して、カスタム トークン化、データ マスク、データの編集、または暗号化メカニズムを実装します。

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

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 を適用します。

-- 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 を示しています。

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

行単位入力のタイムスタンプタイムゾーンの挙動

TIMESTAMP 入力は、UTC のタイムゾーン情報を持たない datetime 値として、行単位の Python UDF に渡されます。 クラシックコンピュートでは、この動作にはDatabricks Runtime 18.1以上が必要です。 サーバーレスコンピュートやプロ・サーバーレスのSQLウェアハウスでは、UDFの environment_version を明示的に 6 以上に設定してください。 datetimeオブジェクトはtzinfo属性にタイムゾーンメタデータを含めていません。

Batch Unity Catalog Python UDF は、タイムスタンプ入力を pandas.Series オブジェクトで受け取り、この datetime マッピングを使用しません。

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

例えば、以下のクエリは環境バージョン6とセッションタイムゾーンをUTCに明示的に設定しています:

SET TIME ZONE 'UTC';

CREATE FUNCTION timezone_udf(date TIMESTAMP)
RETURNS STRING
LANGUAGE PYTHON
ENVIRONMENT (
  environment_version = '6'
)
AS $$
return f"{type(date)} {date} {date.tzinfo}"
$$;

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

以前の実行パスはセッションタイムゾーンにタイムゾーンに対応した値を返します。 これはDatabricks Runtime 18.1以前のクラシックコンピュートに適用されます。 また、サーバーレスコンピュートや、 ENVIRONMENT 節を省略したり、 environment_version = 'None'を設定したり、バージョン6より前のバージョンを選択する場合、プロ・サーバーレスSQLウェアハウスでも適用されます。 セッションタイムゾーンをUTCに設定した場合、前の経路は次のようになります:

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

定義を示すと、サーバーレス計算やプロおよびサーバーレスSQLウェアハウスはPySpark互換の動作を使用しています。 Databricks Runtime 18.1 以降を実行するクラシック コンピューティングでは、ENVIRONMENT 句を調整または省略した場合でも、同じ動作となります:

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

この変化はクロックフィールドだけでなく、 tzinfoにも影響を及ぼします。 インスタント 2024-10-23T10:30:00Zでは、 America/Los_Angeles セッションの前の動作が 2024-10-23 03:30:00-07:00 を生み出します。 新しい挙動により、タイムゾーン素朴なUTC値 2024-10-23 10:30:00が得られます。

もしUDFがタイムゾーン情報に依存している場合は、明示的にUTCを復元してください:

from datetime import timezone

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

UTCタイムゾーン情報を追加しても、以前のセッションローカルクロックフィールドは復元されません。 もしロジックにそれらのフィールドが必要なら、aware値を意図したセッションタイムゾーンに変換してください。 例えば次が挙げられます。

from zoneinfo import ZoneInfo

date = date.astimezone(ZoneInfo("America/Los_Angeles"))

制限事項

  • Python UDF 内には任意の数の Python 関数を定義できますが、すべてスカラー値を返す必要があります。
  • Python 関数は NULL 値を個別に処理する必要があり、すべての型マッピングは Azure Databricks SQL 言語マッピングに従う必要があります。
  • カタログまたはスキーマを指定しない場合、Azure Databricks Python UDF を現在のアクティブなスキーマに登録します。
  • Python UDF は、セキュリティで保護された分離された環境で実行され、ファイル システムや内部サービスにアクセスできません。
  • Databricks Runtime 18.1以上を搭載したクラシックコンピュートでは、5つ以上のUDFをクエリで呼び出すことができます。 サーバーレス計算やプロ・サーバーレスのSQLウェアハウスでは、各UDF定義が environment_version を明示的に 6 以上に設定しなければなりません。