Dela via


Användardefinierade Python-tabellfunktioner (UDF) i Unity Catalog

Viktigt!

Registrering av Python-UDF:er i Unity Catalog finns i offentlig förhandsversion.

Med en användardefinierad tabellfunktion (UDTF) i Unity Catalog kan du registrera funktioner som returnerar fullständiga tabeller i stället för skalära värden. Till skillnad från skalärfunktioner som returnerar ett enda resultatvärde från varje anrop anropas UDF:er i en SQL-instruktionssats FROM och kan returnera flera rader och kolumner.

UDF:er är särskilt användbara för:

  • Omvandla matriser eller komplexa datastrukturer till flera rader
  • Integrera externa API:er eller tjänster i SQL-arbetsflöden
  • Implementera logik för anpassad datagenerering eller berikande
  • Bearbeta data som kräver tillståndskänsliga åtgärder över rader

Varje UDTF-anrop kan acceptera noll eller fler argument. Dessa argument kan vara skalära uttryck eller tabellargument som representerar hela indatatabeller.

UDF:er kan registreras på två sätt:

Kravspecifikation

Python-UDF:er för Unity Catalog stöds på följande beräkningstyper:

  • Klassisk beräkning med standardåtkomstläge (Databricks Runtime 17.1 och senare)
  • SQL-lager (serverlös eller pro)

Skapa en UDTF i Unity-katalogen

Använd SQL DDL för att skapa en styrd UDTF i Unity Catalog. UDF:er anropas med hjälp av en SQL-instruktionssats FROM .

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

Databricks implementerar Python UDTFs som Python-klasser med en obligatorisk eval metod som ger utdatarader.

Miljöisolering

Anmärkning

Delade isoleringsmiljöer kräver Databricks Runtime 17.2 och senare. I tidigare versioner körs alla UTU:er för Unity Catalog Python i strikt isoleringsläge.

Unity Catalog Python-UDF:er med samma ägare och session kan som standard dela en isoleringsmiljö. Detta förbättrar prestanda och minskar minnesanvändningen genom att minska antalet separata miljöer som behöver startas.

Strikt isolering

Lägg till STRICT ISOLATION egenskapssatsen för att säkerställa att en UDTF alltid körs i en egen, helt isolerad miljö.

De flesta UDF:er behöver inte strikt isolering. UDF:er för standarddatabearbetning drar nytta av standardmiljön för delad isolering och körs snabbare med lägre minnesförbrukning.

Lägg till egenskapssatsen STRICT ISOLATION i UDF:er som:

  • Kör indata som kod med hjälp av eval(), exec()eller liknande funktioner.
  • Skriv filer till det lokala filsystemet.
  • Ändra globala variabler eller systemtillstånd.
  • Få åtkomst till eller ändra miljövariabler.

I följande UDTF-exempel anges en anpassad miljövariabel, variabeln läss tillbaka och en uppsättning tal multipliceras med variabeln. Eftersom UDTF muterar processmiljön kör du den i STRICT ISOLATION. Annars kan det läcka eller åsidosätta miljövariabler för andra UDF:er/UDF:er i samma miljö, vilket orsakar felaktigt beteende.

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

Praktiska exempel

Följande exempel visar verkliga användningsfall för UTU:er för Unity Catalog Python, som går från enkla datatransformeringar till komplexa externa integreringar.

Exempel: Implementera om explode

Spark har en inbyggd funktion, men att skapa en egen version visar det grundläggande UDTF-mönstret explode att ta en enda indata och producera flera utdatarader.

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

Använd funktionen direkt i en SQL-fråga:

SELECT element FROM my_explode(array('apple', 'banana', 'cherry'));
+---------+
|| element |
+---------+
|| apple   |
|| banana  |
|| cherry  |
+---------+

Eller tillämpa den på befintliga tabelldata med en LATERAL koppling:

SELECT s.*, e.element
FROM my_items AS s,
LATERAL my_explode(s.items) AS e;

Exempel: IP-adressgeolocation via REST API

Det här exemplet visar hur UDF:er kan integrera externa API:er direkt i ditt SQL-arbetsflöde. I stället för att kräva separata ETL-processer kan analytiker berika data med API-anrop i realtid med hjälp av välbekant SQL-syntax.

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

Anmärkning

Python-UDF:er tillåter TCP/UDP-nätverkstrafik via portarna 80, 443 och 53 när du använder serverlös beräkning eller beräkning som konfigurerats med standardåtkomstläge.

Använd funktionen för att utöka webbloggdata med geografisk information:

SELECT
  l.timestamp,
  l.request_path,
  geo.city,
  geo.country
FROM web_logs AS l,
LATERAL ip_to_location(l.ip_address) AS geo;

Den här metoden möjliggör geografisk analys i realtid utan att kräva förbearbetade uppslagstabeller eller separata datapipelines. UDTF hanterar HTTP-begäranden, JSON-parsning och felhantering, vilket gör externa datakällor tillgängliga via vanliga SQL-frågor.

Ange DETERMINISTIC om funktionen ger konsekventa resultat

Lägg till DETERMINISTIC i funktionsdefinitionen om den genererar samma utdata för samma indata. På så sätt kan frågeoptimeringar förbättra prestandan.

Som standardinställning antas Batch Unity Catalog Python-UDTF:er vara icke-deterministiska om de inte explicit deklareras. Exempel på icke-deterministiska funktioner är: generera slumpmässiga värden, komma åt aktuella tider eller datum eller göra externa API-anrop.

Se CREATE FUNCTION (SQL och Python)

Begränsningar

Följande begränsningar gäller för Unity Catalog Python UDF:er:

Nästa steg