Felhasználó által definiált függvények (UDF-ek) a Unity Katalógusban

Fontos

Ez a funkció a nyilvános előzetes verzióban érhető el.

A Unity Catalog felhasználó által definiált függvényei (UDF-ek) kibővítik az SQL- és Python-képességeket az Azure Databricksben. Lehetővé teszik az egyéni függvények meghatározását, használatát, biztonságos megosztását és szabályozását a számítási környezetekben.

A Unity-katalógusban függvényként regisztrált Python UDF-ek hatóköre és támogatása eltér a pySpark UDF-ektől a jegyzetfüzetig vagy a SparkSessionig. Lásd: Felhasználó által definiált skaláris függvények – Python.

Lásd a teljes SQL nyelvi referenciára a CREATE FUNCTION (SQL és Python) elemeket.

Követelmények

Ha az UDF-eket a Unity Katalógusban szeretné használni, az alábbi követelményeknek kell megfelelnie:

  • Ha Python-kódot szeretne használni a Unity Catalogban regisztrált UDF-ekben, kiszolgáló nélküli vagy pro SQL-tárolót vagy Databricks Runtime 13.3 LTS-t vagy újabb verziót futtató fürtöt kell használnia.
  • Ha egy nézet tartalmaz egy Unity Catalog Python UDF-t, az a klasszikus SQL-tárolókon meghiúsul.
  • A Scala UDF-ekhez készült ARM-példányok támogatása a Unity Catalog-kompatibilis klasztereken a Databricks Runtime 15.2 és ennél újabb verziókban érhető el.

UDF-ek létrehozása a Unity Katalógusban

Az UDF Unity Catalogban történő létrehozásához a felhasználóknak HASZNÁLATI és LÉTREHOZÁSI engedélyre van szükségük a sémára, valamint HASZNÁLATI engedélyre a katalógusra. További részletekért lásd Unity Catalog.

Egy UDF futtatásához a felhasználóknak végrehajtási engedélyre van szükségük az UDF-en. A felhasználóknak használati engedélyre is szükségük van a sémához és a katalógushoz.

Ha egy Egységkatalógus-sémában szeretne UDF-t létrehozni és regisztrálni, a függvény nevének a formátumot catalog.schema.function_namekell követnie. Másik lehetőségként kiválaszthatja a megfelelő katalógust és sémát az SQL-szerkesztőben. Ebben az esetben a függvény neve elé nem szabad catalog.schema-t előtenni:

UDF létrehozása előre kiválasztott katalógussal és sémával.

Az alábbi példa egy új függvényt regisztrál a my_schema katalógus sémájához 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);

A Unity Catalog Python UDF-ek kettős dollárjelekkel ($$) elválasztott utasításokat használnak. Meg kell adnia egy adattípus-leképezést. Az alábbi példa egy olyan UDF-t regisztrál, amely kiszámítja a testtömegindexet:

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

Most már használhatja ezt a Unity Catalog függvényt az SQL-lekérdezésekben vagy a PySpark-kódban:

SELECT person_id, my_catalog.my_schema.calculate_bmi(weight_kg, height_m) AS bmi
FROM person_data;

További UDF-példákért tekintse meg a Sorszűrő és az Oszlopmaszk példákat .

UDF-ek kiterjesztése egyéni függőségek használatával

Fontos

Ez a funkció a nyilvános előzetes verzióban érhető el.

Bővítse a Unity Catalog Python UDF-jeinek funkcióit a Databricks Runtime-környezeten túl a külső kódtárak egyéni függőségeinek definiálásával.

Telepítse a függőségeket a következő forrásokból:

  • PyPI-csomagok
  • Unity-katalógus köteteiben tárolt fájloknak Az UDF-et invokáló felhasználónak READ VOLUME engedélyekkel kell rendelkeznie a forrásköteten.
  • Nyilvános URL-címeken elérhető fájlok A munkaterület hálózati biztonsági szabályainak lehetővé kell tenni a nyilvános URL-címek elérését.

Feljegyzés

Ha hálózati biztonsági szabályokat szeretne konfigurálni a nyilvános URL-címek kiszolgáló nélküli SQL-raktárból való hozzáférésének engedélyezéséhez, olvassa el az Ellenőrzés a Databricks SQL-lel című témakört.

  • A kiszolgáló nélküli SQL-raktárakhoz a nyilvános előzetes funkció Enable networking for isolated workloads in Serverless SQL Warehouses-ot kell engedélyezni a munkaterület Előzetes verzió lapján, hogy az egyéni függőségek számára lehetővé tegye az internet elérését.

A Unity Catalog UDF-jeihez tartozó egyéni függőségek a következő számítási típusok esetében támogatottak:

  • Kiszolgáló nélküli jegyzetfüzetek és feladatok
  • Teljes körű számítás a Databricks Runtime 16.2-es és újabb verziójával
  • Pro vagy szerver nélküli SQL adattárház

A függőségek megadásához használja az UDF-definíció ENVIRONMENT szakaszát:

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 = 'None'
)
AS $$
import simplejson as json
import custom_package
return json.dumps(custom_package.process(data))
$$;

A ENVIRONMENT szakasz a következő mezőket tartalmazza:

Terület Leírás Típus Példa használatra
dependencies A telepíteni kívánt vesszővel tagolt függőségek listája. Minden bejegyzés egy karakterlánc, amely megfelel a pip követelmények fájlformátumának. 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 Azt a kiszolgáló nélküli környezeti verziót adja meg, amelyben az UDF-t futtatni szeretné.
Jelenleg csak a None érték támogatott.
STRING environment_version = 'None'

Használj Unity Catalog UDF-eket a PySparkban

from pyspark.sql.functions import expr

result = df.withColumn("bmi", expr("my_catalog.my_schema.calculate_bmi(weight_kg, height_m)"))
display(result)

Munkamenet-hatókörű UDF frissítése

Feljegyzés

A Unity Catalog pythonos UDF-jeinek szintaxisa és szemantikája eltér a SparkSession-ben regisztrált Python UDF-ektől. Lásd: felhasználó által definiált skaláris függvények – Python.

Tegyük fel, hogy egy Azure Databricks jegyzetfüzetben a következő munkamenet-alapú UDF található:

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

Ha ezt Unity Catalog-függvényként szeretné regisztrálni, használjon egy SQL CREATE FUNCTION utasítást, ahogyan az alábbi példában is látható:

CREATE OR REPLACE FUNCTION my_catalog.my_schema.greet(name STRING)
RETURNS STRING
LANGUAGE PYTHON
AS $$
return f"Hello, {name}!"
$$

UDF-ek megosztása a Unity Katalógusban

Az UDF-ek engedélyeinek kezelése a katalógusra, sémára vagy adatbázisra alkalmazott hozzáférés-vezérlők alapján történik, ahol az UDF regisztrálva van. További információ : Jogosultságok kezelése a Unity Katalógusban .

Az Azure Databricks SQL vagy az Azure Databricks-munkaterület felhasználói felületének használatával adjon engedélyeket egy felhasználónak vagy csoportnak (ajánlott).

Engedélyek a munkaterület felhasználói felületén

  1. Keresse meg azt a katalógust és sémát, amelyben az UDF van tárolva, és válassza ki az UDF-et.
  2. Keresse meg az Engedélyek lehetőséget az UDF beállításai között. Adjon hozzá felhasználókat vagy csoportokat, és adja meg a hozzáférés típusát, például az EXECUTE vagy a MANAGE lehetőséget.

engedélyek a Munkaterület felhasználói felületén

Engedélyek az Azure Databricks SQL használatával

Az alábbi példa az EXECUTE engedélyt ad a felhasználónak egy függvényen:

GRANT EXECUTE ON FUNCTION my_catalog.my_schema.calculate_bmi TO `user@example.com`;

Az engedélyek eltávolításához használja a REVOKE parancsot, ahogyan az alábbi példában látható:

REVOKE EXECUTE ON FUNCTION my_catalog.my_schema.calculate_bmi FROM `user@example.com`;

Környezet izolálása

Feljegyzés

A megosztott elkülönítési környezetekhez a Databricks Runtime 18.0-s vagy újabb verziója szükséges. A korábbi verziókban az összes Unity Catalog Python-UDF szigorú elkülönítési módban fut.

Az azonos tulajdonossal és munkamenettel rendelkező Unity Catalog Python UDF-ek alapértelmezés szerint megoszthatnak egy elkülönítési környezetet. Ez javítja a teljesítményt, és csökkenti a memóriahasználatot az elindítandó különálló környezetek számának csökkentésével.

Szigorú elkülönítés

Annak érdekében, hogy az UDF mindig a saját, teljesen elkülönített környezetben fusson, adja hozzá a STRICT ISOLATION jellemző záradékot.

A legtöbb UDF-nek nincs szüksége szigorú elkülönítésre. A standard adatfeldolgozási UDF-ek kihasználják az alapértelmezett megosztott elkülönítési környezetet, és gyorsabban futnak alacsonyabb memóriahasználat mellett.

Adja hozzá a STRICT ISOLATION jellemző záradékot az olyan UDF-ekhez, amelyek:

  • A beviteli adat futtatása kódként eval(), exec() vagy hasonló függvények használatával.
  • Fájlok írása a helyi fájlrendszerbe.
  • Globális változók vagy rendszerállapot módosítása.
  • Környezeti változók elérése vagy módosítása.

Az alábbi kód egy példát mutat be egy olyan UDF-re, amelyet a következővel STRICT ISOLATIONkell futtatni: Ez az UDF tetszőleges Python-kódot hajt végre, így megváltoztathatja a rendszer állapotát, hozzáférhet a környezeti változókhoz, vagy írhat a helyi fájlrendszerbe. A záradék használata segít megelőzni az STRICT ISOLATION UDF-ek közötti interferencia- vagy adatszivárgást.

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

Állítsa be DETERMINISTIC, ha a függvény következetes eredményeket hoz létre.

Adja hozzá DETERMINISTIC a függvénydefinícióhoz, ha ugyanazokat a kimeneteket állítja elő ugyanazokhoz a bemenetekhez. Ez lehetővé teszi a lekérdezésoptimalizálást a teljesítmény javításához.

Alapértelmezés szerint a Batch Unity Catalog Python UDF-jei nem determinisztikusnak számítanak, kivéve, ha explicit módon deklarálják. A nem determinisztikus függvények például véletlenszerű értékek generálása, az aktuális időpontok vagy dátumok elérése vagy külső API-hívások kezdeményezése.

Lásd CREATE FUNCTION : (SQL és Python)

Az AI-ügynök (agent) eszközeihez használt felhasználó által definiált függvények (UDF-ek)

A Generatív AI-ügynökök eszközként használhatják a Unity Catalog UDF-eket a feladatok végrehajtásához és az egyéni logika végrehajtásához.

Lásd: AI-ügynökeszközök létrehozása Unity Catalog-függvényekkel.

UDF-ek külső API-k eléréséhez

Az UDF-ekkel külső API-kat érhet el az SQL-ből. Az alábbi példa a Python-kódtár requests használatával hoz létre HTTP-kérést.

Feljegyzés

A Python UDF-ek engedélyezik a TCP/UDP hálózati forgalmat a 80-as, a 443-as és az 53-ai porton, amikor kiszolgáló nélküli számítást vagy standard hozzáférési móddal konfigurált számítást használnak.

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

$$;

UDF-ek a biztonság és megfelelés érdekében

Egyéni tokenizálás, adatmaszkolás, adatrejtés vagy titkosítási mechanizmusok implementálása Python UDF-ekkel.

Az alábbi példa elfedi egy e-mail-cím identitását a hossz és a tartomány megőrzése mellett:

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

Az alábbi példa ezt az UDF-et egy dinamikus nézetdefinícióban alkalmazza:

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

Ajánlott eljárások

Ahhoz, hogy az UDF-ek minden felhasználó számára elérhetők legyenek, javasoljuk, hogy hozzon létre egy dedikált katalógust és sémát a megfelelő hozzáférés-vezérléssel.

Csapatspecifikus UDF-ekhez használjon dedikált sémát a csapatkatalógusban a tároláshoz és a felügyelethez.

A Databricks azt javasolja, hogy az alábbi információkat tartalmazza az UDF docstringben:

  • Az aktuális verziószám
  • Változásnapló a verziók módosításainak nyomon követéséhez
  • Az UDF célja, paraméterei és visszatérési értéke
  • Példa az UDF használatára

Íme egy példa egy UDF-re, amely az alábbi ajánlott eljárásokat követi:

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

Időbélyeg időzónának viselkedése bemenetekhez

A Databricks Runtime 18.0-s vagy újabb verziója esetén, amikor TIMESTAMP az értékek a Python UDF-eknek vannak átadva, az értékek UTC-ben maradnak, de az időzóna metaadatai (tzinfo attribútuma) nem szerepelnek az datetime objektumban.

Ez a módosítás összhangba hozza a Unity Catalog Python UDF-jeit az Apache Arrow-ral optimalizált Python UDF-ekkel az Apache Sparkban.

Például a következő lekérdezés:

CREATE FUNCTION timezone_udf(date TIMESTAMP)
RETURNS STRING
LANGUAGE PYTHON
AS $$
return f"{type(date)} {date} {date.tzinfo}"
$$;

SELECT timezone_udf(TIMESTAMP '2024-10-23 10:30:00');

Ezt a kimenetet korábban a Databricks Runtime 18.0 előtti verzióiban állították elő:

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

A Databricks Runtime 18.0-s vagy újabb verziója most a következő kimenetet hozza létre:

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

Ha az UDF az időzónia adataira támaszkodik, kifejezetten vissza kell állítania azokat:

from datetime import timezone

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

Korlátozások

  • A Python UDF-ben tetszőleges számú Python-függvényt definiálhat, de mindegyiknek skaláris értéket kell visszaadnia.
  • A Python-függvényeknek egymástól függetlenül kell kezelnie a NULL értékeket, és minden típusleképezésnek követnie kell az Azure Databricks SQL nyelvi leképezéseit.
  • Ha nincs megadva katalógus vagy séma, a Python UDF-ek regisztrálva lesznek az aktuális aktív sémában.
  • A Python UDF-ek biztonságos, elkülönített környezetben futnak, és nem rendelkeznek hozzáféréssel a fájlrendszerekhez vagy a belső szolgáltatásokhoz.
  • Lekérdezésenként legfeljebb öt UDF-et hívhat meg.