Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Aplica-se a:✅Armazém de dados no Microsoft Fabric
Importante
Esse recurso está na versão prévia.
Em Fabric Data Warehouse, desenvolvedores de T-SQL podem chamar Fabric funções de dados de usuário a partir de consultas T-SQL. Uma função de proxy T-SQL em um armazém de dados chama a função Python referenciada em um item publicado de funções de dados do usuário.
Use essa integração para estender o T-SQL com lógica Python reutilizável para cenários como:
- Utilizando pacotes especializados PyPI para cargas de trabalho espaciais, numéricas ou de ciência de dados.
- Implementando lógica de negócio personalizada em Python.
- Chamando APIs externas.
- Interagir com outros itens do Fabric e serviços do Azure, como depósitos, lakehouses, bancos de dados SQL ou um banco de dados Cosmos.
Este artigo mostra como referenciar uma função de dados de usuário publicada a partir de Fabric Data Warehouse e usá-la em consultas T-SQL.
Pré-requisitos
Para usar as funções de dados do usuário do Fabric Data Warehouse, você precisa:
Um armazém do Fabric.
Um item publicado de funções de dados do usuário que contém a função Python que você deseja invocar.
Acesso de leitura ao item de funções de dados do usuário e permissão para invocar suas funções publicadas.
Permissão para criar uma função no armazém de destino.
Uma função Python que segue o modelo de programação das funções de dados do usuário. Para requisitos de sintaxe, tipos de entrada e saída suportados e uso de decoradores, veja a visão geral do modelo de programação de função de dados do usuário Fabric.
Se você precisar criar um novo item de funções de dados do usuário, também precisa de uma capacidade Fabric em uma região suportada e de um espaço de trabalho Fabric atribuído a essa capacidade. Para detalhes, veja o item Criar funções de dados de usuário em Fabric e Detalhes de Serviço e limitações das funções de dados de usuário do Fabric.
Crie e publique uma função de dados de usuário
Antes de chamar uma função de dados de usuário a partir de um armazém de dados, crie e publique a função em um item de funções de dados de usuário. Para etapas completas e funções de exemplo em Python, veja Criar um item de funções de dados de usuário no Fabric.
Uma função de dados de usuário em Python que você poderia criar é mostrada no exemplo a seguir:
import fabric.functions as fn
udf = fn.UserDataFunctions()
@udf.function()
def hello_fabric(name: str) -> str:
# Your function logic here
return name
Você usa o nome do item da função de dados do usuário para vincular uma função proxy T-SQL à função Python.
Criar uma função proxy T-SQL
Crie uma função T-SQL no seu warehouse e vincule-a à função Python publicada usando a AS EXTERNAL FUNCTION cláusula.
CREATE OR ALTER FUNCTION dbo.hello_fabric
AS EXTERNAL FUNCTION FunctionSetName.hello_fabric;
Substitua FunctionSetName pelo nome do item da sua função de dados de usuário e substitua hello_fabric pelo nome da função Python publicada.
Dica
Você pode gerar o código de invocação a partir da experiência da função de dados do usuário e usá-lo como ponto de partida para a função proxy do warehouse.
Por padrão, a instrução CREATE FUNCTION infere a lista de parâmetros e o tipo de retorno a partir da definição da Fabric User Data Function (UDF) remota. Você pode sobrescrever o tipo de retorno inferido especificando-o explicitamente na definição da função. Fornecer o tipo de retorno é útil quando você deseja expor um tipo de retorno mais preciso do que o tipo inferido a partir dos metadados da função remota.
CREATE OR ALTER FUNCTION dbo.hello_fabric
RETURNS VARCHAR(100)
AS EXTERNAL FUNCTION FunctionSetName.hello_fabric;
Por exemplo, um valor de retorno em Python str é tipicamente inferido como VARCHAR(MAX), mas se a função sempre retorna um valor com comprimento máximo conhecido, você pode definir explicitamente o tipo de retorno como VARCHAR(100) ou outro comprimento apropriado para fornecer metadados e informações de tipo mais precisas.
Use funções proxy em consultas T-SQL
Depois de criar a função proxy, chame-a do T-SQL como qualquer outra função definida pelo usuário.
Use a função proxy em expressões de consulta como:
-
SELECTListas. -
WHEREcláusulas. -
GROUP BYcláusulas. - Expressões em instruções
UPDATEeINSERT.
O padrão a seguir mostra como chamar uma função proxy a partir de uma consulta:
SELECT dbo.<proxy_function_name>(<arguments>) AS function_result;
Para padrões avançados de Python, tipos suportados, conexões e objetos de contexto, veja a visão geral do modelo de programação de funções de dados do usuário Fabric.
Configurar execução em modo batch
Fabric Data Warehouse pode executar funções externas de dados de usuário em modo batch.
A execução em modo batch envia múltiplas invocações de funções em uma única requisição para o serviço remoto Fabric User Data Function (UDF), reduzindo a sobrecarga de rede e a latência de requisição. Um lote pode conter até 900 chamadas de função.
O modo batch é tipicamente usado quando a mesma função é aplicada a valores de uma ou mais colunas de tabelas, permitindo que o processador de consultas avalie muitas linhas em uma única chamada remota, em vez de emitir uma solicitação separada para cada linha. Esse método pode melhorar significativamente o desempenho das consultas, especialmente para grandes conjuntos de dados e chamadas de funções externas de alta latência.
Por exemplo, quando uma consulta aplica uma função de dados de usuário a cada valor de uma coluna, Fabric Data Warehouse pode agrupar os valores de entrada em lotes e enviá-los juntos para processamento remoto. O serviço remoto retorna um lote correspondente de resultados, que são então integrados ao pipeline de execução da consulta.
Para habilitar o modo batch para uma função de dados do usuário:
- Abra o item de funções de dados do usuário .
- Vá para Configurações de gerenciamento> da biblioteca.
- Ative os recursos de Prévia.
Defina max_batch_size=900 no decorador @udf.function() para permitir que o data warehouse envie até 900 linhas de entrada em cada invocação:
Note
O max_batch_size argumento só está disponível quando a pré-visualização em modo batch está ativada.
import fabric.functions as fn
udf = fn.UserDataFunctions()
@udf.function(max_batch_size=900)
def normalizeText(value: str) -> str:
return value.strip().lower()
Após criar uma função proxy T-SQL que faz referência a uma função de dados de usuário (UDF) habilitada por lote, Fabric Data Warehouse detecta automaticamente a configuração em lote, incluindo o tamanho máximo de lote definido pela função remota. Quando o padrão de consulta suporta loteamento, o processador de consultas agrupa múltiplas invocações de funções em lotes e as envia para o serviço remoto para execução, em vez de emitir requisições individuais para cada linha.
Liste as funções de dados de usuário em um data warehouse
As funções de dados do usuário que você cria com AS EXTERNAL FUNCTION aparecem em sys.objects com o tipo de objeto XF.
Para listar as funções de dados do usuário em um depósito, filtre sys.objects por type = 'XF'.
SELECT SCHEMA_NAME(schema_id) AS schema_name, name, object_id, type, type_desc
FROM sys.objects
WHERE type = 'XF';
Para listar tanto funções escalares regulares (FN) quanto funções de dados do usuário (XF) junto com suas assinaturas de parâmetros e tipos de retorno, use sys.parameters e sys.types:
WITH metadata AS
(
SELECT o.schema_id, o.object_id, o.name, p.parameter_id, p.name AS parameter_name, t.name AS type_name
FROM sys.objects AS o
INNER JOIN sys.parameters AS p
ON p.object_id = o.object_id
INNER JOIN sys.types AS t
ON t.user_type_id = p.user_type_id
WHERE o.type IN ('FN', 'XF')
),
signature AS
(
SELECT SCHEMA_NAME(schema_id) AS schema_name,
name,
ANY_VALUE(
CASE WHEN parameter_id = 0 THEN type_name END
) AS return_type,
CONCAT(
SCHEMA_NAME(schema_id),
'.',
name,
'(',
STRING_AGG(
CASE
WHEN parameter_id > 0
THEN CONCAT(parameter_name, ' ', type_name)
END,
', '
) WITHIN GROUP (ORDER BY parameter_id),
') -> ',
MAX(CASE WHEN parameter_id = 0 THEN type_name END)
) AS signature
FROM metadata
GROUP BY schema_id, object_id, name
)
SELECT *
FROM signature;
Observações
- A função de proxy T-SQL depende do item publicado de funções de dados do usuário e do nome da função. Se você renomear ou excluir a função do Python, atualize a função de proxy do armazém de dados conforme necessário.
- O modelo de programação das funções de dados do usuário define os tipos de entrada e saída suportados. Verifique se o parâmetro Python e as anotações de retorno suportam os valores que suas consultas T-SQL passam.
- As funções de dados do usuário possuem limites de serviço para tamanho da carga útil da requisição, tempo de expiração de execução, tamanho da resposta, tamanho da biblioteca e retenção de log. Para os limites atuais, veja Detalhes do serviço e limitações das funções de dados do usuário do Fabric.
- Os nomes dos parâmetros devem usar camelCase e incluir anotações de tipo. Funções decoradas com
@udf.function()também devem especificar um tipo de retorno. Para as regras completas de sintaxe, veja a visão geral do modelo de programação de funções de dados de usuário Fabric. - Para funções de transformação de texto embutidas que não exigem código Python personalizado, veja Usar funções de IA (prévia).
- As funções de dados do usuário possuem limites de serviço para tamanho da carga útil da requisição, tempo de expiração de execução, tamanho da resposta, tamanho da biblioteca e retenção de log. Para os limites atuais, veja Detalhes do serviço e limitações das funções de dados do usuário do Fabric.
- Os nomes dos parâmetros devem usar camelCase e incluir anotações de tipo. Funções decoradas com
@udf.function()também devem especificar um tipo de retorno. Para as regras completas de sintaxe, veja a visão geral do modelo de programação de funções de dados de usuário Fabric. - Para funções de transformação de texto embutidas que não exigem código Python personalizado, veja Usar funções de IA (prévia).
Examples
Os cenários a seguir mostram maneiras comuns de estender Fabric Data Warehouse com funções de dados do usuário.
A. Estenda o T-SQL com análise de endereços IP
Use uma função de dados de usuário em Python quando sua consulta de armazenamento precisar de funcionalidades que não estejam disponíveis como função T-SQL embutida. Por exemplo, você pode usar um pacote de endereço IP para retornar a sub-rede de um endereço IP. Você pode aplicar essa função em lotes quando uma consulta processa endereços IP de várias linhas. Para etapas de configuração, veja Configurar modo batch.
Note
Se a função usar um pacote que não faça parte da biblioteca padrão Python, adicione o pacote no gerenciamento de bibliotecas antes de publicar o item da função de dados do usuário. Este exemplo usa o netaddr pacote.
Defina e publique a função Python em um item de função de dados do usuário:
from netaddr import IPNetwork
import fabric.functions as fn
udf = fn.UserDataFunctions()
@udf.function(max_batch_size=900)
def ipSubnet(ipAddress: str, prefixLength: int = 24) -> str:
return str(IPNetwork(f"{ipAddress}/{prefixLength}").cidr)
Crie uma função proxy T-SQL no warehouse que faça referência à função Python publicada:
CREATE OR ALTER FUNCTION dbo.ip_subnet
AS EXTERNAL FUNCTION inet.ipSubnet;
Chame a função de proxy em uma consulta ao data warehouse:
SELECT dbo.ip_subnet('192.168.1.25', 24) AS subnet;
Resultado esperado:192.168.1.0/24
B. Invocar uma API pública externa
Use uma função de dados de usuário quando uma consulta de warehouse precisar chamar uma API externa como parte de um fluxo de trabalho de enriquecimento de dados.
No banco de dados SQL no Fabric, Banco de Dados SQL do Azure e Instância Gerenciada de SQL do Azure, sys.sp_invoke_external_rest_endpoint invoca um endpoint HTTPS REST. Em Fabric Data Warehouse, uma função de dados do usuário pode fornecer um padrão alternativo ao envolver uma chamada HTTPS em Python e expô-la ao T-SQL por meio de uma função proxy.
Caution
Chamar um endpoint externo pode transferir dados para fora de seu armazém de dados. Use endpoints aprovados, evite enviar dados sensíveis, a menos que isso esteja autorizado, e siga os requisitos de segurança e conformidade da sua organização.
Note
Adicione bibliotecas de terceiros obrigatórias, como requests, no gerenciamento de bibliotecas antes de publicar a função.
Defina e publique a função Python em um item de funções de dados do usuário. Este exemplo usa nomes de parâmetros semelhantes a sys.sp_invoke_external_rest_endpoint:
import json
import requests
import fabric.functions as fn
udf = fn.UserDataFunctions()
@udf.function()
def invokeExternalRestEndpoint(
url: str,
method: str = "GET",
payload: str | None = None,
headers: str | None = None,
timeout: int = 30
) -> str:
requestHeaders = json.loads(headers) if headers else None
requestPayload = payload if payload else None
response = requests.request(
method=method,
url=url,
data=requestPayload,
headers=requestHeaders,
timeout=timeout
)
response.raise_for_status()
return response.text
Crie uma função proxy T-SQL no warehouse:
CREATE OR ALTER FUNCTION dbo.invoke_external_rest_endpoint
AS EXTERNAL FUNCTION api.invokeExternalRestEndpoint;
Chame a função proxy de uma consulta de data warehouse:
SELECT dbo.invoke_external_rest_endpoint(
'https://ipapi.co/8.8.8.8/country_name/',
'GET',
NULL,
NULL,
30
) AS response;
C. Use um período de retenção configurável
Use uma função de dados de usuário quando consultas de armazenamento precisarem de valores de configuração gerenciados centralmente de uma biblioteca de variáveis Fabric. Por exemplo, armazene um período de retenção na biblioteca de variáveis, recupere-o por meio de uma função proxy e use como argumento numérico da DATEADD função T-SQL.
Antes de publicar a função, adicione uma conexão do item de funções de dados do usuário para a biblioteca de variáveis e anote o alias de conexão. A biblioteca de variáveis neste exemplo contém um RETENTION_DAYS valor como 90.
Defina e publique a função Python em um item de função de dados do usuário:
import fabric.functions as fn
udf = fn.UserDataFunctions()
@udf.connection(argName="varLib", alias="WarehouseConfig")
@udf.function()
def getRetentionDays(varLib: fn.FabricVariablesClient) -> int:
variables = varLib.getVariables()
return int(variables["RETENTION_DAYS"])
Substitua WarehouseConfig pelo alias da sua conexão de biblioteca variável.
Crie uma função proxy T-SQL no warehouse:
CREATE OR ALTER FUNCTION dbo.get_retention_days
AS EXTERNAL FUNCTION config.getRetentionDays;
Em uma conexão T-SQL persistente, recupere o valor configurado uma vez e armazene-o usando sp_set_session_context:
DECLARE @retention_days int = dbo.get_retention_days();
EXECUTE sys.sp_set_session_context
@key = N'retention_days',
@value = @retention_days,
@read_only = 1;
O valor permanece disponível durante toda a duração da sessão. Recupere-o com SESSION_CONTEXT e converta-o de sql_variant para int antes de usá-lo com DATEADD e GETDATE. Por exemplo, calcule um corte de retenção:
SELECT DATEADD(
day,
-CONVERT(int, SESSION_CONTEXT(N'retention_days')),
GETDATE()
) AS retention_cutoff;
Reutilize o mesmo valor de sessão em outra instrução para filtrar uma tabela:
SELECT *
FROM dbo.events
WHERE event_timestamp >= DATEADD(
day,
-CONVERT(int, SESSION_CONTEXT(N'retention_days')),
GETDATE()
);
Importante
Use esse padrão de um cliente que mantenha uma conexão T-SQL persistente, como o SQL Server Management Studio ou a extensão MSSQL para Visual Studio Code. O editor de consultas SQL no portal Fabric não suporta sp_set_session_context, e cada execução usa uma sessão separada. Para mais informações, veja limitações do editor de consultas SQL.
Solucionar problemas em funções de dados de usuário
O Query Insights fornece as informações de execução e desempenho que você precisa para solucionar problemas nas funções do Fabric. Você pode identificar consultas que invocaram uma função, determinar se a função usou execução em lote ou linha e investigar latência de serviço externo, tentativas, linhas falhadas e tamanho da carga útil. Use as duas visões a seguir para passar de uma visão geral em nível de consulta para estatísticas detalhadas para cada função:
- Use
queryinsights.exec_requests_historypara identificar consultas que invocaram funções do Fabric ou IA. A visualização inclui o texto da consulta, status, tempo de envio e tempo total decorrido. - Use
queryinsights.external_api_call_statspara obter estatísticas detalhadas para cada função invocada por uma consulta. A visualização inclui o tipo de função, o modo de execução, o número de chamadas e de tentativas, o tempo de espera por serviço externo, o tamanho da carga útil e os resultados por linha.
As visualizações usam distributed_statement_id para identificar a mesma execução da consulta.
Encontre consultas que usaram funções Fabric
Use queryinsights.exec_requests_history para encontrar declarações recentes que invocaram uma função Fabric ou IA:
SELECT TOP 100
h.distributed_statement_id,
h.submit_time,
h.status,
h.total_elapsed_time_ms,
h.command
FROM queryinsights.exec_requests_history AS h
WHERE h.is_using_external_api = 1
ORDER BY h.submit_time DESC;
Copie a distributed_statement_id declaração que você deseja investigar. A próxima consulta filtra as estatísticas detalhadas por funções do Fabric.
Exiba estatísticas para cada função em uma instrução
Substitua <distributed_statement_id> por um identificador retornado pela consulta anterior. A consulta a seguir retorna uma linha para cada função distinta do Fabric invocada pela sentença:
DECLARE @distributed_statement_id uniqueidentifier =
'<distributed_statement_id>';
SELECT function_name,
execution_mode,
call_count,
batch_call_count,
row_call_count,
call_retry_count,
external_service_wait_time_ms,
external_service_wait_time_ms
/ call_count AS average_wait_time_ms_per_call,
rows_total,
rows_succeeded,
rows_failed,
data_sent_bytes,
data_received_bytes
FROM queryinsights.external_api_call_stats
WHERE distributed_statement_id = @distributed_statement_id
AND function_type = 'FABRIC_FUNCTION'
ORDER BY external_service_wait_time_ms DESC;
Os resultados se assemelham ao seguinte exemplo:
| function_name | modo_de_execução | call_count | contagem_de_chamadas_em_lote | row_call_count | call_retry_count | external_service_wait_time_ms | tempo_medio_espera_ms_por_chamada | rows_total | rows_succeeded | linhas_falharam | data_sent_bytes | dados_recebidos_bytes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
inet.ipSubnet |
batch |
12 | 12 | 0 | 0 | 840 | 70 | 600 | 600 | 0 | 12,000 | 9,600 |
api.invokeExternalRestEndpoint |
row |
4 | 0 | 4 | 1 | 1,920 | 480 | 4 | 4 | 0 | 1,024 | 512 |
Dicas de solução de problemas
- Um
row_call_countalto ou um valor derowparaexecution_modepode indicar que a função não está usando execução em lote. Se você espera processamento em lote, confirme que a visualização prévia do modo de lote está habilitada e que a função usa o argumentomax_batch_size. - Use
external_service_wait_time_mseaverage_wait_time_ms_per_callidentifique respostas externas lentas. Se esses valores forem altos edata_sent_bytesdata_received_bytesbaixos, o tempo de resposta do serviço externo provavelmente é o atraso principal. - Valores altos de
data_sent_bytesoudata_received_bytestambém podem aumentar o tempo de execução. Reduza a carga útil de entrada ou saída quando a função transfere mais dados do que o cenário exige.