Unity Catalog 中 (UDF) 的用户定义函数
重要
此功能目前以公共预览版提供。
Unity 目录中的用户定义函数(UDF)扩展了 Azure Databricks 中的 SQL 和 Python 功能。 它们允许在计算环境中定义、使用和安全地共享和管理自定义函数。
在 Unity Catalog 中注册为函数的 Python UDF 在范围和支持方面不同于作用域为笔记本或 SparkSession 的 PySpark UDF。 请参阅用户定义标量函数 - Python。
有关完整的 SQL 语言参考,请参阅 CREATE FUNCTION (SQL 和 Python)。
要求
若要在 Unity 目录中使用 UDF,必须满足以下要求:
- 若要在 Unity Catalog 中注册的 UDF 中使用 Python 代码,必须使用无服务器或 pro SQL 仓库或运行 Databricks Runtime 13.3 LTS 或更高版本的群集。
- 如果视图包含 UC Python UDF,它将在 SQL 经典仓库上失败。
在 Unity 目录中创建 UDF
若要在 Unity 目录中创建 UDF,用户需要对目录的架构和 USAGE 权限具有 USAGE 和 CREATE 权限。 有关更多详细信息,请参阅 Unity 目录 。
若要运行 UDF,用户需要对 UDF 拥有 EXECUTE 权限。 用户还需要对架构和目录具有 USAGE 权限。
以下示例将新函数注册到 my_schema
Unity 目录架构:
CREATE OR REPLACE FUNCTION my_catalog.my_schema.calculate_bmi(weight DOUBLE, height DOUBLE)
RETURNS DOUBLE
LANGUAGE SQL
AS
SELECT weight / (height * height);
Python UDF for Unity 目录使用按双美元符号($$)偏移的语句。 还需要指定数据类型映射。 以下示例注册计算正文质量索引的 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)
$$;
现在可以在 SQL 查询或 PySpark 代码中使用此 Unity 目录函数:
SELECT person_id, my_catalog.my_schema.calculate_bmi(weight_kg, height_m) AS bmi
FROM person_data;
在 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 的权限基于应用于注册 UDF 的目录、架构或数据库的访问控制进行管理。 有关详细信息,请参阅 Unity 目录 。
使用 Azure Databricks SQL 或 Azure Databricks 工作区 UI 向用户或组授予权限(建议)。
工作区 UI 中的权限
- 找到存储 UDF 的目录和架构,然后选择 UDF。
- 在 UDF 设置中查找 “权限” 选项。 添加用户或组并指定他们应具有的访问类型,例如 EXECUTE 或 MANAGE。
![工作区 UI 中的权限](../_static/images/udf/high res udf permission.gif)
使用 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;
UDF 的最佳做法
对于需要可供所有用户访问的 UDF,Databricks 建议使用适当的访问控制创建专用目录和架构。
对于特定于团队的 UDF,请使用团队目录中的专用架构进行存储和管理。
Azure 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
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)
$$;
用于访问外部 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()
# 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 UDF 实现自定义标记化、数据掩码、数据修订或加密机制。
以下示例在保持长度和域的同时屏蔽电子邮件地址的标识:
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 值,并且所有类型映射都必须遵循 Azure Databricks SQL 语言映射。
- 可以导入 Azure Databricks 包含的标准 Python 库,但不能包括自定义库或外部依赖项。
- 如果未指定目录或架构,则 Python UDF 将注册到当前活动架构。
- Python UDF 在安全隔离的环境中执行,无权访问文件系统或内部服务。