Funções de tabela definidas pelo usuário (UDTFs) do Python no Unity Catalog
Visualização
O registro de Python UDTFs no Unity Catalog está em visualização pública.
A função de tabela definida pelo usuário (UDTF) do site Unity Catalog permite registrar funções que retornam tabelas completas em vez de valores escalares. Diferentemente das funções escalares que retornam um único valor de resultado em cada chamada, as UDTFs são invocadas em uma cláusula FROM
de uma instrução SQL e podem retornar várias linhas e colunas.
Os UDTFs são particularmente úteis para:
- Transformando matrizes ou estruturas de dados complexas em várias linhas
- Integração do APIs ou serviço externo ao SQL fluxo de trabalho
- Implementação de lógica personalizada de geração ou enriquecimento de dados
- Processamento de dados que requerem operações com estado entre as linhas
Cada chamada de UDTF pode aceitar zero ou mais argumentos. Esses argumentos podem ser expressões escalares ou argumentos de tabela representando tabelas de entrada inteiras.
Os UDTFs podem ser registrados de duas maneiras:
- Unity CatalogRegistro do UDTF como um objeto governado em Unity Catalog.
- Escopo da sessão: registro para o site local
SparkSession
, isolado para o Notebook ou Job atual. Consulte Funções de tabela definidas pelo usuário (UDTFs) do Python.
Requisitos
Unity Catalog Python Os UDTFs são compatíveis com os seguintes tipos de compute:
- Clássico compute com modo de acesso padrão (Databricks Runtime 17.1 e acima)
- SQL warehouse (serverless, pro e classic)
Criar um UDTF no Unity Catalog
Use SQL DDL para criar um UDTF governado no Unity Catalog. Os UDTFs são invocados usando a cláusula FROM
de uma instrução SQL.
CREATE OR REPLACE FUNCTION square_numbers(start INT, end INT)
RETURNS TABLE (num INT, squared INT)
LANGUAGE PYTHON
HANDLER 'SquareNumbers'
DETERMINISTIC
AS $$
class SquareNumbers:
"""
Basic UDTF that computes a sequence of integers
and includes the square of each number in the range.
"""
def eval(self, start: int, end: int):
for num in range(start, end + 1):
yield (num, num * num)
$$;
SELECT * FROM square_numbers(1, 5);
+-----+---------+
| num | squared |
+-----+---------+
| 1 | 1 |
| 2 | 4 |
| 3 | 9 |
| 4 | 16 |
| 5 | 25 |
+-----+---------+
A Databricks implementa UDTFs Python como classes Python com um método obrigatório eval
que produz linhas de saída.
Isolamento ambiental
Os ambientes de isolamento compartilhado exigem o Databricks Runtime 17.2 e o acima. Em versões anteriores, todos os Unity Catalog Python UDTFs executavam em modo de isolamento estrito.
Unity Catalog Python UDTFs com o mesmo proprietário e sessão podem compartilhar um ambiente de isolamento por meio do site default. Isso melhora o desempenho e reduz o uso de memória ao diminuir o número de ambientes separados que precisam ser iniciados.
Isolamento estrito
Para garantir que uma UDTF seja sempre executada em seu próprio ambiente totalmente isolado, adicione a cláusula característica STRICT ISOLATION
.
A maioria dos UDTFs não precisa de isolamento estrito. Os UDTFs de processamento de dados padrão se beneficiam do ambiente de isolamento compartilhado default e executam mais rapidamente com menor consumo de memória.
Adicione a cláusula característica STRICT ISOLATION
às uDTFs que:
- execução de entrada como código usando
eval()
,exec()
, ou funções semelhantes. - Grave arquivos no sistema de arquivos local.
- Modifique as variáveis globais ou o estado do sistema.
- Acessar ou modificar a variável de ambiente.
O exemplo de UDTF a seguir define uma variável de ambiente personalizada, lê a variável de volta e multiplica um conjunto de números usando a variável. Como a UDTF altera o ambiente do processo, a execução é feita em STRICT ISOLATION
. Caso contrário, poderia vazar ou substituir a variável de ambiente para outros UDFs/UDTFs no mesmo ambiente, causando um comportamento incorreto.
CREATE OR REPLACE TEMPORARY FUNCTION multiply_numbers(factor STRING)
RETURNS TABLE (original INT, scaled INT)
LANGUAGE PYTHON
STRICT ISOLATION
HANDLER 'Multiplier'
AS $$
import os
class Multiplier:
def eval(self, factor: str):
# Save the factor as an environment variable
os.environ["FACTOR"] = factor
# Read it back and convert it to a number
scale = int(os.getenv("FACTOR", "1"))
# Multiply 0 through 4 by the factor
for i in range(5):
yield (i, i * scale)
$$;
SELECT * FROM multiply_numbers("3");
Exemplos práticos
Os exemplos a seguir demonstram casos de uso do mundo real para UDTFs do Unity Catalog Python, progredindo de transformações de dados simples para integrações externas complexas.
Exemplo: Reimplementação explode
Embora o Spark forneça uma função explode
integrada, a criação de sua própria versão demonstra o padrão UDTF fundamental de receber uma única entrada e produzir várias linhas de saída.
CREATE OR REPLACE FUNCTION my_explode(arr ARRAY<STRING>)
RETURNS TABLE (element STRING)
LANGUAGE PYTHON
HANDLER 'MyExplode'
DETERMINISTIC
AS $$
class MyExplode:
def eval(self, arr):
if arr is None:
return
for element in arr:
yield (element,)
$$;
Use a função diretamente em uma consulta SQL:
SELECT element FROM my_explode(array('apple', 'banana', 'cherry'));
+---------+
|| element |
+---------+
|| apple |
|| banana |
|| cherry |
+---------+
Ou aplique-o aos dados da tabela existente com um LATERAL
join:
SELECT s.*, e.element
FROM my_items AS s,
LATERAL my_explode(s.items) AS e;
Exemplo: Geolocalização de endereço IP via API REST
Este exemplo demonstra como os UDTFs podem integrar APIs externas diretamente em seu fluxo de trabalho SQL. Em vez de exigir processos ETL separados, o analista pode enriquecer os dados com chamadas API de tempo real usando a sintaxe SQL conhecida.
CREATE OR REPLACE FUNCTION ip_to_location(ip_address STRING)
RETURNS TABLE (city STRING, country STRING)
LANGUAGE PYTHON
HANDLER 'IPToLocationAPI'
AS $$
class IPToLocationAPI:
def eval(self, ip_address):
import requests
api_url = f"https://api.ip-lookup.example.com/{ip_address}"
try:
response = requests.get(api_url)
response.raise_for_status()
data = response.json()
yield (data.get('city'), data.get('country'))
except requests.exceptions.RequestException as e:
# Return nothing if the API request fails
return
$$;
Python Os UDTFs permitem o tráfego de rede TCP/UDP pelas portas 80, 443 e 53 ao usar serverless compute ou compute configurado com o modo de acesso padrão.
Use a função para enriquecer os dados da Web log com informações geográficas:
SELECT
l.timestamp,
l.request_path,
geo.city,
geo.country
FROM web_logs AS l,
LATERAL ip_to_location(l.ip_address) AS geo;
Essa abordagem permite a análise geográfica em tempo real sem a necessidade de tabelas de pesquisa pré-processadas ou um pipeline de dados separado. O UDTF lida com solicitações HTTP, análise de JSON e tratamento de erros, tornando as fontes de dados externas acessíveis por meio de consultas padrão em SQL.
Defina DETERMINISTIC
se sua função produzir 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.
Em default, os lotes Unity Catalog Python UDTFs são considerados não determinísticos, a menos que sejam declarados explicitamente. Exemplos de funções não determinísticas incluem: geração de valores aleatórios, acesso a horários ou datas atuais ou chamadas de API externas.
Consulte CREATE FUNCTION (SQL e Python)
Limitações
As seguintes limitações se aplicam aos UDTFs do Unity Catalog Python:
- As funções de tabela polimórfica não são suportadas.
- O argumento TABLE não é suportado.
- Não há suporte para as credenciais de serviço do Unity Catalog.
- Não há suporte para dependências personalizadas.