Funções definidas pelo usuário (UDFs) em SQL e Python no Unity Catalog

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 você defina, use e compartilhe com segurança e governe funções personalizadas 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. Consulte Python UDFs (funções escalares definidas pelo usuário).

Para registrar UDFs escritos em Scala ou Java no Catálogo do Unity, consulte Scala e Java UDFs (funções definidas pelo usuário) no Catálogo do Unity.

Para ver quais cargas de trabalho e tabelas referenciam um UDF no Unity Catalog antes de modificá-lo, veja Visualizar linhagem do UDF.

Consulte CREATE FUNCTION (SQL, Python, Scala e Java) 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 Python do Unity Catalog, ela falhará em warehouses SQL clássicos.
  • O suporte a instâncias ARM para UDFs Scala em clusters habilitados para Unity Catalog está disponível no Databricks Runtime 15.2 e superior.

As UDFs em Python escalares e em lote do Unity Catalog geralmente estão disponíveis em todos os tipos de computação suportados.

Requisitos da funcionalidade Python UDF

Os requisitos variam conforme a característica. O Databricks Runtime 19 e o ambiente versão 6 não são requisitos gerais para UDFs Python do Unity Catalog.

Para UDFs de sessão do PySpark em notebooks serverless ou jobs, os requisitos do ambiente referem-se ao ambiente da sessão. Para UDFs de Python definidas por SQL, fazem referência a environment_version na cláusula ENVIRONMENT de cada função. Mudar o ambiente de sessão não altera o ambiente de uma função existente do Catálogo Unity. Por exemplo, uma sessão usando a versão 6 do ambiente pode chamar uma função do Catálogo Unity definida com a versão 5 do ambiente.

Característica Requisitos
ENVIRONMENT cláusula e dependências personalizadas Notebooks e trabalhos sem servidor; repositórios SQL pro ou sem servidor; Databricks Runtime 16.2 ou superior em computação clássica. Na computação clássica executando o Databricks Runtime 16.2 a 18.1, environment_version deve ser 'None'.
UDFs Python do Catálogo do Unity em Lote computação sem servidor; armazéns SQL pro e sem servidor; Databricks Runtime 16.3 ou superior no modo de computação clássica
Handler nomeado para um UDF escalar de Python Databricks Runtime 18.1 ou superior em ambiente de computação clássico. Em computação serverless e em SQL warehouses Pro e Serverless, defina explicitamente o(a) environment_version da UDF como 6 ou superior.
Credenciais de serviço em um UDF escalar de Python Databricks Runtime 18.1 ou superior em ambiente de computação clássico. Em computação serverless e em SQL warehouses Pro e Serverless, defina explicitamente o(a) environment_version da UDF como 6 ou superior. A computação clássica não requer a versão 6 do ambiente. Nos SQL warehouses sem servidor, também ative a visualização pública de rede para carga de trabalho isolada.
Credenciais de serviço em um UDF Python do Catálogo Batch Unity Computação serverless; reposiões SQL pro e serverless; Databricks Runtime 16.3 ou superior na computação clássica. A versão 6 do ambiente não é obrigatória. Nos SQL warehouses sem servidor, também ative a visualização pública de rede para carga de trabalho isolada.
Segredos em um escalar ou UDF do Catálogo Batch Unity em Python Defina explicitamente environment_version como 6 ou superior; computação serverless; SQL warehouses Pro e serverless; Databricks Runtime 19 ou superior com modo de acesso padrão em computação clássica. A invocação direta não é suportada em computação em modo de acesso dedicado.
Comportamento de entrada compatível TIMESTAMP com PySpark Databricks Runtime 18.1 ou superior em ambiente de computação clássico. Em computação serverless e em SQL warehouses Pro e Serverless, defina explicitamente o(a) environment_version da UDF como 6 ou superior.
Mais de cinco chamadas de UDF em uma consulta Databricks Runtime 18.1 ou superior em ambiente de computação clássico. Em computação sem servidor e em data warehouses SQL profissionais e sem servidor, defina explicitamente o environment_version de cada UDF como 6 ou superior.

UDFs e recursos existentes que estavam disponíveis durante a Versão Preliminar Pública continuam funcionando em versões de tempo de execução anteriores aplicáveis.

A versão do ambiente também determina se os chamadores precisam de acesso direto às dependências armazenadas em um volume do Unity Catalog. Veja Permissões para dependências em volumes do Catálogo Unity.

Versões de ambiente na computação clássica

Na computação clássica, a definição de environment_version como um valor diferente de 'None' requer o Databricks Runtime 18.2 ou superior. No Databricks Runtime 16.2 a 18.1, defina environment_version = 'None' sempre que você usar a cláusula ENVIRONMENT. O valor 'None' usa o ambiente padrão do Python.

No Databricks Runtime 18.2 ou superior, para comportamento previsível, o Azure Databricks recomenda definir explicitamente um environment_version fixo em cada definição de Python UDF do Catálogo do Unity. Escolha uma versão que atenda aos requisitos de recursos do UDF e siga estas recomendações de compatibilidade:

Versão do Databricks Runtime Versão máxima recomendada do ambiente
18.2 a 18.x 5
19.x 6

Criando UDFs em SQL e Python no Unity Catalog

Para criar uma UDF em SQL ou Python 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 anexado a ela:

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

O exemplo a seguir registra uma nova função no esquema my_schema do catálogo 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);

As UDFs do Python para o Unity Catalog 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.

Use um manipulador nomeado em uma UDF escalar em Python

Na computação clássica, handlers nomeados requerem a versão 18.1 ou superior do Databricks Runtime. Em computação serverless e em SQL warehouses Pro e Serverless, defina explicitamente o(a) environment_version da UDF como 6 ou superior. O exemplo a seguir usa o ambiente versão 6. Na computação clássica executando o Databricks Runtime 18.1, omita a cláusula ENVIRONMENT. Em versões de runtime posteriores, siga as recomendações de compatibilidade se você incluir a cláusula.

Use a HANDLER cláusula para nomear uma função Python no corpo do UDF como ponto de entrada. O handler nomeado aceita os argumentos UDF e retorna um valor que corresponde ao tipo de retorno declarado. Código fora do handler é executado quando cada ambiente Python inicializa o UDF, antes que o handler processe as entradas. Use esse código para inicialização única que pode ser reutilizada entre chamadas de handler.

O exemplo a seguir inicializa greeting_prefix antes de definir greet_handler, a função que lida com entradas UDF:

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

Usar segredos em uma UDF Python

UDFs Python escalares e em lote do Unity Catalog podem acessar segredos declarados na cláusula SECRETS. A definição do UDF deve definir environment_version explicitamente como 6 ou acima. Um segredo do Catálogo Unity usa um nome em três partes (catalog.schema.secret) e é distinto de um segredo do Azure Databricks em nível de espaço de trabalho. Para suporte a computação, permissões e a exceção de máscara de coluna para computação dedicada, consulte requisitos e permissões de UDF.

Para acessar um segredo de uma UDF:

  1. Adicione o nome de três partes do segredo à cláusula SECRETS na definição da UDF. Uma UDF só pode recuperar segredos declarados nessa cláusula.
  2. No corpo da UDF, chame databricks.secrets.get() com o catálogo, o esquema e o nome do segredo.

O exemplo de UDF escalar a seguir usa um segredo do Unity Catalog como chave de assinatura para um código de autenticação de mensagem baseado em hash (HMAC). Use a mesma cláusula SECRETS com PARAMETER STYLE PANDAS para acessar segredos declarados de um manipulador de UDF em lote.

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

Não retorne valores secretos a partir de uma UDF. A redação de segredos ajuda a reduzir a exposição acidental em erros e logs, mas não impede que o código UDF exponha material secreto nos resultados das consultas.

Estender UDFs usando dependências personalizadas

Observação

Para instalar dependências personalizadas da internet em um SQL Warehouse sem servidor, seu espaço de trabalho deve ter o recurso de Visualização Pública Habilitar rede para cargas de trabalho isoladas em SQL Warehouses sem servidor habilitado na página Visualizações.

Você pode estender as capacidades das UDFs Python do Unity Catalog para além do ambiente de execução do Databricks Runtime ao definir dependências personalizadas para bibliotecas externas.

Requisitos

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 clássica de todos os fins usando o Databricks Runtime versão 16.2 e superior
  • SqL Warehouse pro ou sem servidor

Fontes de dependência

Instale dependências das seguintes fontes:

Observação

Se o workspace restringir o acesso à rede sem servidor, você deverá configurar regras de segurança de rede para permitir as URLs públicas. Consulte Definir regras de saída.

Permissões para dependências em volumes do Catálogo Unity

O criador da função deve ter READ VOLUME em um volume de origem para adicionar uma dependência desse volume a uma UDF.

Para uma UDF cuja definição define explicitamente environment_version como 6 ou acima, quem chama a UDF precisa ter EXECUTE na UDF, mas não precisa ter READ VOLUME no volume de origem. Se a definição do UDF omitir environment_version, defini-lo como None ou defini-lo como uma versão anterior, os chamadores também deverão ter READ VOLUME no volume de origem.

Definir dependências

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 = '6'
)
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 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. 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 Especifica a versão do ambiente para rodar o UDF. Esse campo é obrigatório sempre que a ENVIRONMENT cláusula estiver presente. Uma versão de ambiente fixa executa a UDF com uma versão Python específica e um conjunto de pacotes pré-instalados, independentemente da versão Python e dos pacotes no Databricks Runtime subjacente.
Os valores compatíveis são uma versão do ambiente 3 ou acima, como '6', ou a string 'None'. O valor 'None' seleciona o ambiente Python padrão. Na computação clássica, a definição de environment_version como um valor diferente de 'None' requer o Databricks Runtime 18.2 ou superior. No Databricks Runtime 16.2 a 18.1, somente 'None' tem suporte. Quando versões fixas do ambiente tiverem suporte, selecione explicitamente uma para comportamento previsível.
Em computação serverless e em repositórios SQL pro e serverless, alguns recursos exigem uma versão explícita do ambiente. Defina environment_version como a versão necessária ou superior em cada definição de UDF. Omitir toda a cláusula ENVIRONMENT ou definir environment_version = 'None' não habilita esses recursos. Veja requisitos de recursos do Python UDF.
Para compatibilidade de versões no compute clássico, consulte Versões de ambiente na computação clássica. Para ver a lista de versões disponíveis, consulte Versões de ambiente.
STRING environment_version = '6'

Usar UDFs 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

Os controles de acesso aplicados ao catálogo, esquema ou banco de dados em que você registra o UDF gerencia suas permissões. 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`;

Isolamento de ambiente

Observação

Ambientes de isolamento compartilhado exigem o Databricks Runtime 18.1 ou superior. Em versões anteriores, todas as UDFs do Python no Unity Catalog executavam no modo de isolamento estrito.

UDFs Python do Unity Catalog com o mesmo proprietário e a mesma sessão podem compartilhar um ambiente de isolamento por padrão. Isso melhora o desempenho e reduz o uso de memória reduzindo o número de ambientes separados que devem ser iniciados.

Isolamento estrito

Para verificar se uma UDF sempre é executada em seu próprio ambiente totalmente isolado, adicione a cláusula característica STRICT ISOLATION.

A maioria das UDFs não precisa de isolamento estrito. As UDFs de processamento de dados padrão se beneficiam do ambiente de isolamento compartilhado padrão e são executadas mais rapidamente com menor consumo de memória.

Adicione a cláusula característica STRICT ISOLATION nas UDFs que:

  • Execute a entrada como código usando eval(), exec()ou funções semelhantes.
  • Gravar arquivos no sistema de arquivos local.
  • Modificar variáveis globais ou estado do sistema.
  • Acesse ou modifique variáveis de ambiente.

O código a seguir mostra um exemplo de uma UDF que deve ser executada usando STRICT ISOLATION. Essa UDF executa código Python arbitrário, portanto, pode alterar o estado do sistema, acessar variáveis de ambiente ou gravar no sistema de arquivos local. O uso da STRICT ISOLATION cláusula ajuda a evitar interferências ou vazamentos de dados em UDFs.

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

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, o Azure Databricks trata as UDFs Python em lote do Unity Catalog como não determinísticas, a menos que você declare explicitamente o contrário. 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, Python, Scala e Java)

UDFs para ferramentas de agente

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

Consulte Criar ferramentas de agente 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 ao usar a computação sem servidor ou a 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()
   # Assume 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 |
+---+------------+------------------------+------------------------+

Práticas recomendadas

Para que as UDFs sejam acessíveis a todos os usuários, o Databricks recomenda a criação de um catálogo e um esquema dedicados com controles de acesso apropriados.

Para UDFs específicas de equipe, use um esquema dedicado no catálogo da 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

O exemplo a seguir mostra uma UDF que segue 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)
$$;

Comportamento de fuso horário do carimbo de data/hora para entradas linha por linha

Um valor de entrada TIMESTAMP chega a uma UDF Python processada linha por linha como um valor datetime sem fuso horário em UTC. Na computação clássica, esse comportamento requer Databricks Runtime 18.1 ou superior. Em computação serverless e em SQL warehouses Pro e Serverless, defina explicitamente o(a) environment_version da UDF como 6 ou superior. O datetime objeto não inclui metadados de fuso horário em seu tzinfo atributo.

UDFs Python em lote do Unity Catalog recebem entradas de timestamp em objetos pandas.Series e não usam esse mapeamento datetime.

Essa alteração alinha UDFs do Python no Unity Catalog com UDFs do Python otimizadas com Arrow no Apache Spark.

Por exemplo, a consulta a seguir define explicitamente a versão 6 do ambiente e o fuso horário da sessão para 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');

O caminho de execução anterior retorna um valor com reconhecimento de fuso horário no fuso horário da sessão. Isso se aplica ao processamento clássico antes do Databricks Runtime 18.1. Também se aplica em computação serverless e em warehouses SQL pro e serverless quando você omite a ENVIRONMENT cláusula, define environment_version = 'None'ou seleciona uma versão anterior à 6. Com o fuso horário da sessão definido para UTC, o caminho anterior produz:

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

Com a definição mostrada, a computação sem servidor e os armazéns SQL Pro e sem servidor usam o comportamento compatível com o PySpark. A computação clássica executando o Databricks Runtime 18.1 ou superior usa o mesmo comportamento quando você ajusta ou omite a cláusula ENVIRONMENT:

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

Essa mudança pode afetar os campos de relógio, bem como tzinfo. No instante 2024-10-23T10:30:00Z, o comportamento anterior em uma sessão America/Los_Angeles produz 2024-10-23 03:30:00-07:00. O novo comportamento produz o valor UTC sem fuso horário 2024-10-23 10:30:00.

Se seu UDF depende de informações de fuso horário, restaure o UTC explicitamente:

from datetime import timezone

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

Adicionar informações do fuso horário UTC não restaura os campos do relógio locais da sessão anterior. Se sua lógica precisar desses campos, também converta o valor consciente para o fuso horário da sessão pretendido. Por exemplo:

from zoneinfo import ZoneInfo

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

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 você não especificar um catálogo ou esquema, o Azure Databricks registra as UDFs do Python no esquema ativo no momento.
  • Python UDFs são executados em um ambiente seguro e isolado e não têm acesso a sistemas de arquivos ou serviços internos.
  • Você pode chamar mais de cinco UDFs em uma consulta na computação clássica executando o Databricks Runtime 18.1 ou superior. Em computação sem servidor e em data warehouses SQL profissionais e sem servidor, cada definição de UDF deve definir explicitamente environment_version como 6 ou superior.