Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Aplica-se para:✅ Armazém no Microsoft Fabric
Importante
Este recurso está em pré-visualização.
No Fabric Data Warehouse, os programadores de T-SQL podem chamar funções de dados do utilizador do Fabric a partir de consultas T-SQL. Uma função proxy T-SQL num armazém de dados chama a função Python referenciada num item publicado de funções de dados do utilizador.
Use esta integração para estender o T-SQL com lógica Python reutilizável para cenários como:
- Utilização de pacotes especializados PyPI para cargas de trabalho espaciais, numéricas ou de ciência de dados.
- Implementar lógica de negócio personalizada em Python.
- Invocar APIs externas.
- Interagir com outros itens do Fabric e serviços do Azure, como warehouses, lakehouses, bases de dados SQL ou uma Cosmos DB.
Este artigo mostra como referenciar uma função de dados de utilizador publicada a partir de Fabric Data Warehouse e utilizá-la em consultas T-SQL.
Pré-requisitos
Para utilizar as funções de dados do utilizador a partir de Fabric Data Warehouse, precisa de:
Um armazém de tecidos.
Um item publicado de funções de dados de utilizador que contém a função Python que pretende invocar.
Acesso de leitura ao item de funções de dados do utilizador e permissão para invocar as suas funções publicadas.
Permissão para criar uma função no armazém alvo.
Uma função em Python que segue o modelo de programação das funções de dados do utilizador. 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ções de utilizador do Fabric.
Se precisares de criar um novo item de funções de dados de utilizador, também precisas de uma capacidade Fabric numa região suportada e de um espaço de trabalho Fabric atribuído a essa capacidade. Para mais detalhes, veja o item Criar funções de dados de utilizador em Fabric e Detalhes e limitações das funções de dados de utilizador do Fabric.
Criar e publicar uma função de dados de utilizador
Antes de poder chamar uma função de dados de utilizador a partir de um armazém, crie e publique a função num item de funções de dados de utilizador. Para passos completos e funções de exemplo em Python, consulte Criar um item de funções de dados de utilizador no Fabric.
Uma função de dados de utilizador em Python que poderia criar é mostrada no seguinte exemplo:
import fabric.functions as fn
udf = fn.UserDataFunctions()
@udf.function()
def hello_fabric(name: str) -> str:
# Your function logic here
return name
Usas o nome do item da função de dados de utilizador para associar uma função proxy T-SQL à função Python.
Criar uma função proxy T-SQL
Crie uma função T-SQL no seu armazém e associe-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 de funções de dados do utilizador e hello_fabric pelo nome da função Python publicada.
Sugestão
Pode gerar o código de invocação a partir da experiência das funções de dados do utilizador e usá-lo como ponto de partida para a função proxy do armazém.
Por defeito, 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. Pode sobrescrever o tipo de retorno inferido especificando-o explicitamente na definição da função. Fornecer o tipo de retorno é útil quando se pretende 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 devolver sempre um valor com um comprimento máximo conhecido, pode definir explicitamente o tipo de retorno como VARCHAR(100) ou outro comprimento apropriado para fornecer metadados e informação de tipo mais precisas.
Usar funções proxy em consultas T-SQL
Depois de criares a função proxy, chama-a a partir do T-SQL como qualquer outra função definida pelo utilizador.
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 seguinte 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 em Python, tipos suportados, ligações e objetos de contexto, veja a visão geral do modelo de programação de funções de utilizador do Fabric.
Configurar a execução em modo batch
Fabric Data Warehouse pode executar funções de dados de utilizador externos em modo batch.
A execução em modo batch envia múltiplas invocações de funções num único pedido para o serviço remoto Fabric User Data Function (UDF), reduzindo a sobrecarga da rede e a latência dos pedidos. 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 da tabela, permitindo ao processador de consultas avaliar muitas linhas numa única chamada remota em vez de emitir um pedido separado para cada linha. Este método pode melhorar significativamente o desempenho das consultas, especialmente para conjuntos de dados grandes e chamadas de funções externas de alta latência.
Por exemplo, quando uma consulta aplica uma função de dados de utilizador a cada valor de uma coluna, Fabric Data Warehouse pode agrupar os valores de entrada em lotes e submetê-los juntos para processamento remoto. O serviço remoto devolve um lote correspondente de resultados, que são então integrados no pipeline de execução da consulta.
Para ativar o modo batch para uma função de dados de utilizador:
- Abra o item de funções de dados do utilizador .
- Vá àsDefiniçõesde Gestão> da Biblioteca.
- Ativa as funcionalidades de Pré-visualização.
Defina max_batch_size=900 no decorador @udf.function() para permitir que o armazém de dados envie até 900 linhas de entrada em cada invocação:
Note
O argumento max_batch_size 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()
Depois de criar uma função proxy T-SQL que referencia uma função de dados de utilizador (UDF) habilitada por lote, Fabric Data Warehouse deteta 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 envia-as para o serviço remoto para execução, em vez de emitir pedidos individuais para cada linha.
Listar funções de dados de utilizador num armazém
As funções de dados do utilizador que criar com AS EXTERNAL FUNCTION aparecem em sys.objects com o tipo de objeto XF.
Para listar as funções de dados do utilizador num armazém, 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 as funções escalares regulares (FN) como as funções de dados do utilizador (XF) juntamente com as 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;
Remarks
- A função de proxy T-SQL depende do item de funções de dados de utilizador publicadas e do nome da função. Se renomear ou eliminar a função Python, atualize a função proxy do warehouse em conformidade.
- O modelo de programação das funções de dados do utilizador 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 as suas consultas T-SQL passam.
- As funções de dados do utilizador têm limites de serviço para o tamanho da carga útil dos pedidos, tempo de expiração de execução, tamanho da resposta, tamanho da biblioteca e retenção de registos. Para os limites atuais, consulte Detalhes do serviço e limitações das funções de dados do utilizador do Fabric.
- Os nomes dos parâmetros devem usar camelCase e incluir anotações de tipo. As 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 utilizador do Fabric. - Para funções de transformação de texto incorporadas que não requerem código Python personalizado, veja Usar funções de IA (pré-visualização).
- As funções de dados do utilizador têm limites de serviço para o tamanho da carga útil dos pedidos, tempo de expiração de execução, tamanho da resposta, tamanho da biblioteca e retenção de registos. Para os limites atuais, consulte Detalhes do serviço e limitações das funções de dados do utilizador do Fabric.
- Os nomes dos parâmetros devem usar camelCase e incluir anotações de tipo. As 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 utilizador do Fabric. - Para funções de transformação de texto incorporadas que não requerem código Python personalizado, veja Usar funções de IA (pré-visualização).
Examples
Os cenários seguintes mostram formas comuns de estender Fabric Data Warehouse com funções de dados do utilizador.
A. Estender T-SQL com análise de endereços IP
Use uma função de dados de utilizador em Python quando a sua consulta de armazém precisar de funcionalidades que não estejam disponíveis como função T-SQL incorporada. Por exemplo, pode usar um pacote de endereços IP para obter a sub-rede correspondente a um endereço IP. Pode aplicar esta função em lotes quando uma consulta processa endereços IP de várias linhas. Para os passos de configuração, veja Configurar o modo batch.
Note
Se a função usar um pacote que não faz parte da biblioteca padrão Python, adicione o pacote na gestão de bibliotecas antes de publicar o item da função de dados do utilizador. Este exemplo utiliza o netaddr pacote.
Defina e publique a função Python num item de função de dados do utilizador:
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 armazém que faça referência à função Python publicada:
CREATE OR ALTER FUNCTION dbo.ip_subnet
AS EXTERNAL FUNCTION inet.ipSubnet;
Invocar a função de proxy a partir de uma consulta ao armazém de dados:
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 utilizador quando uma consulta de armazém precisar de chamar uma API externa como parte de um fluxo de trabalho de enriquecimento de dados.
Na base de dados SQL do Fabric, na Base de Dados SQL do Azure e na Instância Gerida de SQL do Azure, sys.sp_invoke_external_rest_endpoint invoca um ponto final REST HTTPS. Em Fabric Data Warehouse, uma função de dados do utilizador pode fornecer um padrão alternativo ao envolver uma chamada HTTPS em Python e expô-la a T-SQL através de uma função proxy.
Caution
Chamar um endpoint externo pode transferir dados para fora do seu armazém de dados. Use endpoints aprovados, evite enviar dados sensíveis a menos que autorizado e cumpra os requisitos de segurança e conformidade da sua organização.
Note
Adicione bibliotecas de terceiros obrigatórias, como requests, na gestão de bibliotecas antes de publicar a função.
Defina e publique a função Python num item de funções de dados do utilizador. Este exemplo utiliza 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 armazém:
CREATE OR ALTER FUNCTION dbo.invoke_external_rest_endpoint
AS EXTERNAL FUNCTION api.invokeExternalRestEndpoint;
Chame a função de proxy numa consulta ao armazém de dados:
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 utilizador quando as consultas de armazém necessitem de valores de configuração geridos centralmente a partir de uma biblioteca de variáveis Fabric. Por exemplo, armazenar um período de retenção na biblioteca de variáveis, recuperá-lo através de uma função proxy e usá-lo como argumento numérico da DATEADD função T-SQL.
Antes de publicar a função, adicione uma ligação do item das funções de dados do utilizador à biblioteca de variáveis e anote o alias de ligação. A biblioteca de variáveis neste exemplo contém um RETENTION_DAYS valor como 90.
Defina e publique a função Python num item de função de dados do utilizador:
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"])
Substitui WarehouseConfig pelo alias da ligação à tua biblioteca de variáveis.
Crie uma função proxy T-SQL no armazém:
CREATE OR ALTER FUNCTION dbo.get_retention_days
AS EXTERNAL FUNCTION config.getRetentionDays;
Numa ligaçã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. Recupera-o com SESSION_CONTEXT e converte-o de sql_variant para int antes de o utilizar 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 noutra instrução para filtrar uma tabela:
SELECT *
FROM dbo.events
WHERE event_timestamp >= DATEADD(
day,
-CONVERT(int, SESSION_CONTEXT(N'retention_days')),
GETDATE()
);
Importante
Utilize este padrão de um cliente que mantenha uma ligaçã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, consulte limitações do editor de consultas SQL.
Resolver problemas das funções de dados do utilizador
O Query Insights fornece a informação de execução e desempenho necessária para diagnosticar funções do Fabric. Pode identificar consultas que invocaram uma função, determinar se a função usou execução por lote ou por linha, e investigar a latência de serviço externo, tentativas, linhas falhadas e o tamanho da carga útil. Use as seguintes duas vistas para passar de uma visão geral ao nível da consulta para estatísticas detalhadas para cada função:
-
queryinsights.exec_requests_historyUse para identificar consultas que invocaram funções de Fabric ou IA. A visualização inclui o texto da consulta, estado, tempo de submissão e tempo total decorrido. -
queryinsights.external_api_call_statsUse para 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, a contagem de chamadas e de novas tentativas, o tempo de espera do serviço externo, o tamanho da carga útil e os resultados por linha.
As vistas usam distributed_statement_id para identificar a execução da mesma 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 o distributed_statement_id da declaração que pretende investigar. A consulta seguinte filtra as estatísticas detalhadas para funções Fabric.
Ver estatísticas para cada função numa instrução
Substitua <distributed_statement_id> por um identificador devolvido pela consulta anterior. A consulta seguinte devolve uma linha para cada função Fabric distinta invocada pela afirmação:
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 assemelham-se ao seguinte exemplo:
| function_name | execution_mode | call_count | batch_call_count | row_call_count | número_de_tentativas_de_repetição_de_chamada | tempo_de_espera_do_serviço_externo_ms | tempo_medio_de_espera_ms_por_chamada | rows_total | linhas_com_sucesso | rows_failed | 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 |
Sugestões de resolução de problemas
- Um valor alto de
row_call_countou um valor deexecution_modederowpode indicar que a função não está a usar execução em lote. Se esperares processamento em lote, confirma que a pré-visualização do modo em lote está ativada 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 estes valores forem altos edata_sent_bytesdata_received_bytesbaixos, o tempo de resposta do serviço externo é provavelmente o atraso principal. - Valores grandes
data_sent_bytesdata_received_bytestambém podem aumentar o tempo de execução. Reduzir a carga útil de entrada ou saída se a função transferir mais dados do que o cenário exige.