Unity Catalog 中 (UDF) 的用户定义函数

重要

此功能目前以公共预览版提供。

Azure Databricks 提供 SQL 本机语法,用于将自定义函数注册到受 Unity Catalog 管理的架构。 在 Unity Catalog 中注册为函数的 Python UDF 在范围和支持方面不同于作用域为笔记本或 SparkSession 的 PySpark UDF。 请参阅用户定义标量函数 - Python

有关完整的 SQL 语言参考,请参阅 CREATE FUNCTION (SQL 和 Python)

有关 Unity Catalog 如何管理函数权限的信息,请参阅 CREATE FUNCTION

要求

  • Databricks Runtime 13.3 LTS 或更高版本。
  • 要在 Unity Catalog 中注册的 UDF 中使用 Python 代码,必须使用专业 SQL 仓库或运行 Databricks Runtime 13.3 LTS 或更高版本的群集。
  • 要解析使用注册到 Unity Catalog 的 UDF 创建的视图,必须使用专业 SQL 仓库。

Unity Catalog 中的自定义 SQL 函数

使用为 Unity Catalog 配置的计算创建 SQL 函数时,该函数默认注册到当前活动架构。 以下示例演示了可用于声明新函数的目标目录和架构的语法:

CREATE FUNCTION target_catalog.target_schema.roll_dice()
    RETURNS INT
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    COMMENT 'Roll a single 6 sided die'
    RETURN (rand() * 6)::INT + 1;

然后,对函数具有足够权限的所有用户都可以在为 Unity Catalog 配置的计算环境中使用该函数,如以下示例所示:

SELECT target_catalog.target_schema.roll_dice()

注意

可以使用利用 LANGUAGE SQL 的 UDF 返回表或标量值。

将 Python UDF 注册到 Unity Catalog

在 Databricks Runtime 13.3 LTS 及更高版本中,可以使用 SQL CREATE FUNCTION 语句将标量 Python UDF 注册到 Unity Catalog。

重要

如果要使用 SQL 仓库在 Unity Catalog 中注册 Python UDF,它必须是 Pro SQL 仓库。

Python UDF 旨在直接在 SQL 函数中提供 Python 的完整表现力,允许自定义操作,例如高级转换、数据掩码和哈希。

Python UDF 在安全隔离的环境中执行,无权访问文件系统或内部服务。

在 Databricks Runtime 13.3 LTS 至 14.2 中,在无服务器计算或共享访问模式下运行的 Python UDF 允许通过端口 80、443 和 53 传输 TCP/UDP 网络流量。

请参阅哪些 UDF 最高效?

注意

Unity Catalog 中 Python UDF 的语法和语义不同于注册到 SparkSession 的 Python UDF。 请参阅用户定义标量函数 - Python

适用于 Unity Catalog 的 Python UDF 使用语句由双美元符号 ($$) 设置,如以下代码示例所示:

CREATE FUNCTION target_catalog.target_schema.greet(s STRING)
RETURNS STRING
LANGUAGE PYTHON
AS $$
  return f"Hello, {s}"
$$

以下示例演示如何使用此函数返回存储在名为 students 的表的 first_name 列中的所有名称的 greeting 语句:

SELECT target_catalog.target_schema.greet(first_name)
FROM students;

可以在 Python UDF 中定义任意数量的 Python 函数,但必须返回标量值。

Python 函数必须独立处理 NULL 值,并且所有类型映射都必须遵循 Azure Databricks SQL 语言映射

可以导入 Azure Databricks 包含的标准 Python 库,但不能包括自定义库或外部依赖项。

如果未指定目录或架构,则 Python UDF 将注册到当前活动架构。

以下示例导入库并在 Python UDF 中使用多个函数:

CREATE FUNCTION roll_dice(num_dice INTEGER, num_sides INTEGER)
RETURNS INTEGER
LANGUAGE PYTHON
AS $$
  import numpy as np

  def roll_die(num_sides):
    return np.random.randint(num_sides) + 1

  def sum_dice(num_dice,num_sides):
    return sum([roll_die(num_sides) for x in range(num_dice)])

  return sum_dice(num_dice, num_sides)
$$