Compartilhar via


UDFs (funções definidas pelo usuário) no Catálogo do Unity

Importante

Esse recurso está em uma versão prévia.

As UDFs (funções definidas pelo usuário) no Catálogo do Unity estendem os recursos do SQL e do Python no Azure Databricks. Eles permitem que funções personalizadas sejam definidas, usadas e compartilhadas e controladas com segurança em ambientes de computação.

As UDFs do Python registradas como funções no Catálogo do Unity diferem no escopo e o suporte de UDFs do PySpark com escopo para um notebook ou SparkSession. Confira Funções escalares definidas pelo usuário – Python.

Consulte CREATE FUNCTION (SQL e Python) para obter uma referência completa da linguagem SQL.

Requisitos

Para usar UDFs no Catálogo do Unity, você deve atender aos seguintes requisitos:

  • Para usar o código Python em UDFs registrados no Catálogo do Unity, você deve usar um SQL Warehouse sem servidor ou pro ou um cluster executando o Databricks Runtime 13.3 LTS ou superior.
  • Se uma exibição incluir uma UDF do Python uc, ela falhará em sql warehouses clássicos.

Criando UDFs no Catálogo do Unity

Para criar uma UDF no Unity Catalog, os usuários precisam das permissões USAGE e CREATE no esquema, e da permissão USAGE no catálogo. Consulte o Catálogo do Unity para obter mais detalhes.

Para executar uma UDF, os usuários precisam da permissão EXECUTE na UDF. Os usuários também precisam da permissão USAGE no esquema e no catálogo.

Para criar e registrar um UDF em um esquema do Catálogo do Unity, o nome da função deve seguir o formato catalog.schema.function_name. Como alternativa, você pode selecionar o catálogo e o esquema corretos no Editor de SQL. Nesse caso, o nome da função não deve ter catalog.schema sido acrescentado a ele:

Criando uma UDF com o catálogo e o esquema pré-selecionados.

O exemplo a seguir registra uma nova função no my_schema esquema no my_catalog catálogo:

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

As UDFs do Python para o Catálogo do Unity usam instruções delimitadas por cifrões duplos ($$). Você deve especificar um mapeamento de tipo de dados. O exemplo a seguir registra uma UDF que calcula o índice de massa corporal:

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

Agora você pode usar essa função do Catálogo do Unity em suas consultas SQL ou código PySpark:

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

Veja exemplos de filtro de linha e exemplos de máscara de coluna para obter mais exemplos de UDF.

Estender UDFs usando dependências personalizadas

Importante

Esse recurso está em uma versão prévia.

Estenda a funcionalidade dos UDFs do Python no Unity Catalog além do ambiente do Databricks Runtime, definindo dependências personalizadas para bibliotecas externas.

Instale dependências das seguintes fontes:

  • Pacotes de PyPI
  • Arquivos armazenados em volumes do Catálogo do Unity O usuário que invoca a UDF deve ter READ VOLUME permissões no volume de origem.
  • Arquivos disponíveis em URLs públicas As regras de segurança de rede do workspace devem permitir o acesso a URLs públicas.

Observação

Para configurar regras de segurança de rede para permitir o acesso a URLs públicas de um SQL Warehouse sem servidor, consulte Validar com o SQL do Databricks.

  • Os sql warehouses sem servidor exigem que o recurso de Visualização Pública Habilite a rede para UDFs em SQL Warehouses sem servidor para serem habilitados na página Visualizações do seu workspace para acessar a Internet para dependências personalizadas.

O suporte para dependências customizadas para UDFs do Unity Catalog está disponível nos seguintes tipos de computação:

  • Notebooks e trabalhos sem servidor
  • Computação para todos os fins usando o Databricks Runtime versão 16.2 e superior
  • SqL Warehouse clássico ou profissional

Use a ENVIRONMENT seção da definição de UDF para especificar dependências:

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

A ENVIRONMENT seção contém os seguintes campos:

Campo Descrição Tipo Exemplo de uso
dependencies STRING Uma lista de dependências separadas por vírgulas a serem instaladas. Cada entrada é uma cadeia de caracteres que está em conformidade com o formato de arquivo pip Requirements. 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 STRING Especifica a versão do ambiente sem servidor na qual executar o UDF.
Atualmente, há suporte apenas para o valor None .
environment_version = 'None'

Usando a UDF do Catálogo do Unity no PySpark

from pyspark.sql.functions import expr

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

Atualizar uma UDF com escopo de sessão

Observação

A sintaxe e a semântica para UDFs do Python no Catálogo do Unity diferem das UDFs do Python registradas para o SparkSession. Consulte funções escalares definidas pelo usuário - Python.

Dada a seguinte UDF baseada em sessão em um notebook do Azure Databricks:

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()

Para registrar isso como uma função do Catálogo do Unity, use uma instrução SQL CREATE FUNCTION , como no exemplo a seguir:

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

Compartilhar UDFs no Catálogo do Unity

As permissões para UDFs são gerenciadas com base nos controles de acesso aplicados ao catálogo, esquema ou banco de dados em que a UDF está registrada. Consulte Gerenciar privilégios no Catálogo do Unity para obter mais informações.

Use o SQL do Azure Databricks ou a interface do usuário do workspace do Azure Databricks para conceder permissões a um usuário ou grupo (recomendado).

Permissões na interface do usuário do workspace

  1. Localize o catálogo e o esquema em que sua UDF está armazenada e selecione a UDF.
  2. Procure por uma opção de 'Permissões' nas configurações de UDF. Adicione usuários ou grupos e especifique o tipo de acesso que eles devem ter, como EXECUTE ou MANAGE.

Permissões na interface do usuário da área de trabalho

Permissões usando o SQL do Azure Databricks

O exemplo a seguir concede a um usuário a permissão EXECUTE em uma função:

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

Para remover permissões, use o REVOKE comando como no exemplo a seguir:

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

Práticas recomendadas para UDFs

Para que as UDFs sejam acessíveis a todos os usuários, recomendamos criar um catálogo e um esquema dedicados com controles de acesso apropriados.

Para UDFs específicos da equipe, use um esquema dedicado no catálogo de equipe para armazenamento e gerenciamento.

O Databricks recomenda que você inclua as seguintes informações no docstring da UDF:

  • O número da versão atual
  • Um changelog para rastrear modificações entre versões
  • A finalidade, os parâmetros e o valor retornado da UDF
  • Um exemplo de como usar a UDF

Aqui está um exemplo de uma UDF seguindo as práticas recomendadas:

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

Definir DETERMINISTIC se sua função produz resultados consistentes

Adicione DETERMINISTIC à sua definição de função se ela produzir as mesmas saídas para as mesmas entradas. Isso permite otimizações de consulta para melhorar o desempenho.

Por padrão, as UDFs do Python do Catálogo do Unity do Lote são consideradas não determinísticas, a menos que explicitamente declaradas. Exemplos de funções não determinísticas incluem gerar valores aleatórios, acessar datas ou horários atuais ou fazer chamadas à API externa.

Consulte CREATE FUNCTION (SQL e Python)

Funções Definidas pelo Usuário (UDF) para ferramentas de agentes de IA

Agentes de IA generativos podem usar UDFs do Catálogo do Unity como ferramentas para executar tarefas e executar lógica personalizada.

Confira Criar ferramentas personalizadas de agentes de IA usando funções do Catálogo do Unity.

UDFs para acessar APIs externas

Você pode usar UDFs para acessar APIs externas do SQL. O exemplo a seguir usa a biblioteca Python requests para fazer uma solicitação HTTP.

Observação

As UDFs do Python permitem o tráfego de rede TCP/UDP nas portas 80, 443 e 53 usando computação sem servidor ou computação configurada com o modo de acesso padrão.

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

$$;

UDFs para segurança e conformidade

Use UDFs do Python para implementar tokenização personalizada, mascaramento de dados, redação de dados ou mecanismos de criptografia.

O exemplo a seguir mascara a identidade de um endereço de e-mail, mantendo o comprimento e o domínio:

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}"
$$

O exemplo a seguir aplica essa UDF em uma definição de exibição dinâmica:

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

Limitações

  • Você pode definir qualquer número de funções do Python em uma UDF do Python, mas todas devem retornar um valor escalar.
  • As funções do Python devem lidar com valores NULL de forma independente e todos os mapeamentos de tipo devem seguir os mapeamentos de linguagem SQL do Azure Databricks.
  • Se nenhum catálogo ou esquema for especificado, as UDFs do Python serão registradas no esquema ativo atual.
  • As UDFs do Python são executadas em um ambiente seguro e isolado e não têm acesso a sistemas de arquivos ou serviços internos.
  • Você não pode chamar mais de cinco UDFs por consulta.