Aller au contenu principal

Fonctions définies par l'utilisateur (UDF) SQL et Python dans Unity Catalog

Les fonctions définies par l'utilisateur (UDF) dans Unity Catalog étendent les capacités SQL et Python au sein de Databricks. Ils vous permettent de définir, d'utiliser, de partager et de gérer en toute sécurité des fonctions personnalisées dans différents environnements informatiques.

Les fonctions UDF Python enregistrées en tant que fonctions dans Unity Catalog diffèrent en termes de portée et de prise en charge des fonctions UDF PySpark limitées à un notebook ou à une SparkSession. Voir les fonctions scalaires définies par l'utilisateur Python (UDF).

Pour enregistrer les UDF écrites en Scala ou en Java dans Unity Catalog, consultez Fonctions définies par l'utilisateur (UDF) Scala et Java dans Unity Catalog.

Pour voir quels workloads et tables référencent une UDF dans Unity Catalog avant de la modifier, consultez Afficher la traçabilité des UDF.

Consultez la référence linguistique SQL complète (CREATE FUNCTION, SQL, Python, Scala et Java).

Exigences

Pour utiliser des UDF dans Unity Catalog, vous devez remplir les exigences suivantes :

  • Pour utiliser du code Python dans les UDF enregistrées dans Unity Catalog, vous devez utiliser un SQL warehouse serverless ou Pro ou un cluster exécutant Databricks Runtime 13.3 LTS ou une version ultérieure.
  • Si une vue inclut une UDF Python Unity Catalog, elle échoue sur les SQL Warehouse classiques.
  • La prise en charge des instances ARM pour les UDF Scala sur les clusters activés pour Unity Catalog est disponible dans Databricks Runtime 15,2 et versions ultérieures.

Les UDF Python scalaires et Batch Unity Catalog sont généralement disponibles sur tous les types de compute pris en charge.

Exigences de la fonctionnalité Python UDF

Les exigences varient selon la fonctionnalité. Databricks Runtime 19 et la version 6 de l'environnement ne sont pas des exigences générales pour les UDF Python de Unity Catalog.

Pour les UDF de session PySpark sur les notebooks ou les jobs serverless, les exigences en matière d’environnement font référence à l’environnement de session. Pour les UDF Python définies par SQL, elles font référence à environment_version dans la clause ENVIRONMENT de chaque fonction. Modifier l’environnement de session ne modifie pas l’environnement d’une fonction Unity Catalog existante. Par exemple, une session utilisant la version d’environnement 6 peut appeler une fonction Unity Catalog définie avec la version d’environnement 5.

Fonctionnalité

Exigences

ENVIRONMENT clause et dépendances personnalisées

Notebooks et jobs serverless ; Databricks Runtime 16.2 ou une version ultérieure sur le compute classique ; SQL Warehouses Pro ou serverless

UDF Python Batch Unity Catalog

Compute serverless ; SQL Warehouses Pro et serverless ; Databricks Runtime 16.3 ou supérieur sur compute classique

Gestionnaire nommé pour une UDF Python scalaire

Databricks Runtime 18.1 ou version supérieure sur le compute classique. Sur le compute Serverless et sur les SQL Warehouse Pro et Serverless, définissez explicitement le paramètre environment_version de l’UDF sur 6 ou une valeur supérieure.

Informations d’identification de service dans une UDF Python scalaire

Databricks Runtime 18.1 ou version ultérieure sur un compute classique. Sur le compute serverless et sur les SQL Warehouses pro et serverless, définissez explicitement le environment_version de l’UDF sur 6 ou une version supérieure. Le compute classique ne nécessite pas la version d’environnement 6. Sur les SQL Warehouses serverless, activez également la prévisualisation publique de la mise en réseau des charges de travail isolées.

Identifiants de service dans une UDF Python Batch Unity Catalog

Compute serverless ; SQL warehouses Pro et serverless ; Databricks Runtime 16.3 ou version ultérieure sur le compute classique. La version 6 de l’environnement n’est pas requise. Sur les SQL Warehouses Serverless, activez également la prévisualisation publique de la mise en réseau des charges de travail isolées.

Secrets dans une UDF Python scalaire ou Batch Unity Catalog

Définissez explicitement environment_version sur 6 ou une version ultérieure ; compute serverless ; SQL warehouses Pro et serverless ; Databricks Runtime 19 ou une version ultérieure avec le mode d'accès standard sur un compute classique. L'appel direct n'est pas pris en charge sur le compute en mode d'accès dédié.

Comportement d’entrée TIMESTAMP compatible avec PySpark

Databricks Runtime 18.1 ou version supérieure sur le compute classique. Sur le compute Serverless et sur les SQL Warehouse Pro et Serverless, définissez explicitement le paramètre environment_version de l’UDF sur 6 ou une valeur supérieure.

Plus de cinq appels d'UDF dans une query

Databricks Runtime 18.1 ou version ultérieure sur le compute classique. Sur le compute Serverless et sur les SQL Warehouse Pro et Serverless, définissez explicitement chaque environment_version de l'UDF sur 6 ou une version ultérieure.

Fonctionnalité

Exigences

ENVIRONMENT clause et dépendances personnalisées

Notebooks et jobs serverless ; Databricks Runtime 16.2 ou une version ultérieure sur le compute classique ; SQL Warehouses Pro ou serverless

UDF Python Batch Unity Catalog

Compute serverless ; SQL Warehouses Pro et serverless ; Databricks Runtime 16.3 ou supérieur sur compute classique

Gestionnaire nommé pour une UDF Python scalaire

Databricks Runtime 18.1 ou version supérieure sur le compute classique. Sur le compute Serverless et sur les SQL Warehouse Pro et Serverless, définissez explicitement le paramètre environment_version de l’UDF sur 6 ou une valeur supérieure.

Informations d’identification de service dans une UDF Python scalaire

Databricks Runtime 18.1 ou version ultérieure sur un compute classique. Sur le compute serverless et sur les SQL Warehouses pro et serverless, définissez explicitement le environment_version de l’UDF sur 6 ou une version supérieure. Le compute classique ne nécessite pas la version d’environnement 6. Sur les SQL Warehouses serverless, activez également la prévisualisation publique de la mise en réseau des charges de travail isolées.

Identifiants de service dans une UDF Python Batch Unity Catalog

Compute serverless ; SQL warehouses Pro et serverless ; Databricks Runtime 16.3 ou version ultérieure sur le compute classique. La version 6 de l’environnement n’est pas requise. Sur les SQL Warehouses Serverless, activez également la prévisualisation publique de la mise en réseau des charges de travail isolées.

Secrets dans une UDF Python scalaire ou Batch Unity Catalog

Définissez explicitement environment_version sur 6 ou une version ultérieure ; compute serverless ; SQL warehouses Pro et serverless ; Databricks Runtime 19 ou une version ultérieure avec le mode d'accès standard sur un compute classique. L'appel direct n'est pas pris en charge sur le compute en mode d'accès dédié.

Comportement d’entrée TIMESTAMP compatible avec PySpark

Databricks Runtime 18.1 ou version supérieure sur le compute classique. Sur le compute Serverless et sur les SQL Warehouse Pro et Serverless, définissez explicitement le paramètre environment_version de l’UDF sur 6 ou une valeur supérieure.

Plus de cinq appels d'UDF dans une query

Databricks Runtime 18.1 ou version ultérieure sur le compute classique. Sur le compute Serverless et sur les SQL Warehouse Pro et Serverless, définissez explicitement chaque environment_version de l'UDF sur 6 ou une version ultérieure.

Les UDF et fonctionnalités existantes qui étaient disponibles pendant l'aperçu public continuent de fonctionner sur les versions de runtime antérieures applicables.

La version d’environnement détermine également si les appelants ont besoin d’un accès direct aux dépendances stockées dans un volume Unity Catalog. Voir Autorisations relatives aux dépendances dans les volumes Unity Catalog.

Versions d'environnement sur le compute classique

Pour un comportement prévisible, Databricks recommande de définir explicitement environment_version dans chaque définition d'UDF Python Unity Catalog. Sur le compute classique, choisissez une version qui répond aux exigences de la fonction de l'UDF et suit ces recommandations de compatibilité Databricks Runtime :

Version de Databricks Runtime

Version d’environnement maximale recommandée

17.x

4

18.x

5

19.x

6

Version de Databricks Runtime

Version d’environnement maximale recommandée

17.x

4

18.x

5

19.x

6

Création d'UDF SQL et Python dans Unity Catalog

Pour créer une UDF SQL ou Python dans Unity Catalog, les utilisateurs ont besoin des autorisations USAGE et CREATE sur le schéma, et de l'autorisation USAGE sur le catalogue. Consultez Unity Catalog pour plus de détails.

Pour exécuter une UDF, les utilisateurs ont besoin d'une autorisation EXECUTE sur l'UDF. Les utilisateurs ont également besoin de l'autorisation USAGE sur le schéma et le catalogue.

Pour créer et enregistrer une UDF dans un schéma Unity Catalog, le nom de la fonction doit suivre le format catalog.schema.function_name. Alternativement, vous pouvez sélectionner le catalogue et le schéma corrects dans l'éditeur SQL. Dans ce cas, le nom de votre fonction ne doit pas être précédé de catalog.schema :

Création d'une UDF avec le catalogue et le schéma présélectionnés.

L'exemple suivant enregistre une nouvelle fonction dans le schéma my_schema du catalogue my_catalog :

SQL
CREATE OR REPLACE FUNCTION my_catalog.my_schema.calculate_bmi(weight DOUBLE, height DOUBLE)
RETURNS DOUBLE
LANGUAGE SQL
RETURN
SELECT weight / (height * height);

Les UDF Python pour Unity Catalog utilisent des instructions décalées par des doubles signes dollar ($$). Vous devez spécifier un mappage de type de données. L'exemple suivant enregistre une UDF qui calcule l'indice de masse corporelle :

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

Vous pouvez maintenant utiliser cette fonction Unity Catalog dans vos requêtes SQL ou votre code PySpark :

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

Voir les exemples de filtres de ligne et les exemples de masques de colonne pour d'autres exemples d'UDF.

Utiliser un gestionnaire nommé dans une UDF Python scalaire

Sur le compute classique, les gestionnaires nommés nécessitent Databricks Runtime 18.1 ou une version ultérieure. Sur le Serverless compute ainsi que sur les SQL Warehouse Pro et Serverless, définissez explicitement le paramètre environment_version de l'UDF sur 6 ou une version ultérieure.

Utilisez la clause HANDLER pour nommer une fonction Python dans le corps de l'UDF en tant que point d'entrée. Le gestionnaire nommé accepte les arguments de l'UDF et renvoie une valeur qui correspond au type de retour déclaré. Le code situé en dehors du gestionnaire s'exécute lorsque chaque environnement Python initialise l'UDF, avant que le gestionnaire ne traite les entrées. Utilisez ce code pour une initialisation à usage unique qui peut être réutilisée entre les appels de gestionnaire.

L’exemple suivant initialise greeting_prefix avant de définir greet_handler, la fonction qui gère les entrées d’UDF :

SQL
CREATE OR REPLACE FUNCTION my_catalog.my_schema.greet(name STRING)
RETURNS STRING
LANGUAGE PYTHON
HANDLER 'greet_handler'
ENVIRONMENT (
environment_version = '6'
)
AS $$
# Runs once when each Python environment initializes the UDF.
greeting_prefix = "Hello"

def greet_handler(name):
return f"{greeting_prefix}, {name}!"
$$;

Utiliser des secrets dans une UDF Python

Les UDF Python Scalar et Batch Unity Catalog peuvent accéder aux secrets déclarés dans la clause SECRETS. La définition de l’UDF doit explicitement définir environment_version sur 6 ou une valeur supérieure. Un secret Unity Catalog utilise un nom en trois parties (catalog.schema.secret) et se distingue d’un secret Databricks au niveau du workspace. Pour en savoir plus sur la prise en charge du compute, les autorisations et l’exception relative au masquage de colonne pour le compute dédié, consultez la section UDF requirements and permissions.

Pour accéder à un secret à partir d'une UDF :

  1. Ajoutez le nom en trois parties du secret à la clause SECRETS dans la définition de l'UDF. Une UDF peut récupérer uniquement les secrets déclarés dans cette clause.
  2. Dans le corps de la UDF, appelez databricks.secrets.get() avec le catalogue, le schéma et le nom du secret.

L’exemple d’UDF scalaire suivant utilise un secret Unity Catalog comme clé de signature HMAC (Hash-based Message Authentication Code). Utilisez la même clause SECRETS avec PARAMETER STYLE PANDAS pour accéder aux secrets déclarés à partir d'un gestionnaire UDF batch.

SQL
CREATE OR REPLACE FUNCTION main.default.sign_value(value STRING)
RETURNS STRING
LANGUAGE PYTHON
SECRETS (main.default.hmac_key)
ENVIRONMENT (
environment_version = '6'
)
AS $$
import hashlib
import hmac
from databricks.secrets import get

key = get(catalog="main", schema="default", key="hmac_key")
return hmac.new(key.encode(), value.encode(), hashlib.sha256).hexdigest()
$$;
attention

Ne renvoyez pas de valeurs secrètes à partir d'une UDF. La rédaction des secrets contribue à réduire l'exposition accidentelle dans les erreurs et les logs, mais elle n'empêche pas le code UDF d'exposer du matériel secret dans les résultats de query.

Étendre les UDF à l'aide de dépendances personnalisées

remarque

Pour installer des dépendances personnalisées depuis Internet sur un SQL Warehouse Serverless, votre Workspace doit disposer de la fonctionnalité en Public Preview Activer la mise en réseau pour les charges de travail isolées dans les SQL Warehouses Serverless activée sur la page d'aperçu.

Vous pouvez étendre les capacités des UDF Python Unity Catalog au-delà de l'environnement Databricks Runtime en définissant des dépendances personnalisées pour les bibliothèques externes.

Exigences

Les dépendances personnalisées pour les UDF Unity Catalog sont prises en charge sur les types de compute suivants :

  • Notebooks et Jobs Serverless
  • Compute classique tout usage utilisant Databricks Runtime version 16.2 et supérieures
  • SQL Warehouse Pro ou Serverless
remarque

Le compute serverless ne garantit pas d’architecture CPU spécifique. Les notebooks serverless, les jobs et les warehouses SQL serverless peuvent s'exécuter sur aarch64 ou x86_64, et l'architecture peut changer entre les exécutions ou les redémarrages. Étant donné qu'une UDF Python Unity Catalog peut s'exécuter sur une architecture différente de celle où ses dépendances ont été créées, ses dépendances doivent prendre en charge toutes les architectures que le compute appelant est susceptible d'utiliser.

Si une dépendance est un Python wheel avec des extensions natives (C), son binaire précompilé est spécifique à l'architecture. Une roue construite pour une seule architecture ne parvient pas à s'installer sur l'autre, renvoyant une erreur ISOLATION_ENVIRONMENT_USER_ERROR.GENERIC. Pour éviter cela, incluez les variantes de roue aarch64 et x86_64 dans dependencies et contraintes à leur architecture respective avec un platform_machine marqueur d'environnement.

Sources de dépendance

Installez les dépendances à partir des sources suivantes :

remarque

Si votre Workspace restreint l'accès réseau serverless, vous devez configurer des règles de sécurité réseau pour autoriser les URL publiques. Voir Définir les règles de sortie.

Autorisations pour les dépendances dans les volumes Unity Catalog

Le créateur de la fonction doit disposer de READ VOLUME sur un volume source pour ajouter une dépendance de ce volume à une UDF.

Pour une UDF dont la définition définit explicitement environment_version sur 6 ou supérieur, les appelants ont besoin de EXECUTE sur l’UDF mais n’ont pas besoin de READ VOLUME sur le volume source. Si la définition de l’UDF omet environment_version, le définit sur None ou le définit sur une version antérieure, les appelants doivent également disposer de READ VOLUME sur le volume source.

Définir les dépendances

Utilisez la section ENVIRONMENT de la définition de l’UDF pour spécifier les dépendances :

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

La section ENVIRONMENT contient les champs suivants :

Champ

Description

Type

Exemple d’utilisation

dependencies

Une liste de dépendances séparées par des virgules à installer. Chaque entrée est une chaîne qui est conforme au format de fichier d'exigences pip.

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

Spécifie la version de l'environnement dans laquelle exécuter l'UDF. Ce champ est obligatoire chaque fois que la clause ENVIRONMENT est présente. Une version d'environnement fixe exécute l'UDF avec une version Python spécifique et un ensemble de packages préinstallés, indépendamment de la version Python et des packages présents dans le Databricks Runtime sous-jacent.

Les valeurs prises en charge sont une version d'environnement de 3 ou supérieure, telle que '6', ou la chaîne 'None'. La valeur 'None' sélectionne l'environnement Python par default. Pour un comportement prévisible, veuillez sélectionner explicitement une version d'environnement fixe.

Sur le compute serverless ainsi que sur les SQL Warehouses Pro et serverless, certaines fonctionnalités nécessitent une version d’environnement explicite. Définissez environment_version sur la version requise ou supérieure dans chaque définition d’UDF. L’omission de l’intégralité de la clause ENVIRONMENT ou la définition de environment_version = 'None' n’activent pas ces fonctionnalités. Consultez les exigences de la fonctionnalité Python UDF.

Sur le compute classique, suivez les recommandations relatives aux versions d’environnement. Pour consulter la liste des versions disponibles, voir Versions d’environnement.

STRING

environment_version = '6'

Champ

Description

Type

Exemple d’utilisation

dependencies

Une liste de dépendances séparées par des virgules à installer. Chaque entrée est une chaîne qui est conforme au format de fichier d'exigences pip.

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

Spécifie la version de l'environnement dans laquelle exécuter l'UDF. Ce champ est obligatoire chaque fois que la clause ENVIRONMENT est présente. Une version d'environnement fixe exécute l'UDF avec une version Python spécifique et un ensemble de packages préinstallés, indépendamment de la version Python et des packages présents dans le Databricks Runtime sous-jacent.

Les valeurs prises en charge sont une version d'environnement de 3 ou supérieure, telle que '6', ou la chaîne 'None'. La valeur 'None' sélectionne l'environnement Python par default. Pour un comportement prévisible, veuillez sélectionner explicitement une version d'environnement fixe.

Sur le compute serverless ainsi que sur les SQL Warehouses Pro et serverless, certaines fonctionnalités nécessitent une version d’environnement explicite. Définissez environment_version sur la version requise ou supérieure dans chaque définition d’UDF. L’omission de l’intégralité de la clause ENVIRONMENT ou la définition de environment_version = 'None' n’activent pas ces fonctionnalités. Consultez les exigences de la fonctionnalité Python UDF.

Sur le compute classique, suivez les recommandations relatives aux versions d’environnement. Pour consulter la liste des versions disponibles, voir Versions d’environnement.

STRING

environment_version = '6'

Utiliser des UDF Unity Catalog dans PySpark

Python
from pyspark.sql.functions import expr

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

Mettre à niveau une UDF à l'étendue de la session

remarque

La syntaxe et la sémantique des UDF Python dans Unity Catalog diffèrent de celles des UDF Python enregistrées auprès de la SparkSession. Consultez les fonctions scalaires définies par l'utilisateur – Python.

Étant donné l'UDF basée sur une session suivante dans un notebook Databricks :

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

Pour l'enregistrer en tant que fonction Unity Catalog, utilisez une instruction SQL CREATE FUNCTION, comme dans l'exemple suivant :

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

Partager des UDF dans Unity Catalog

Les contrôles d'accès appliqués au catalogue, au schéma ou à la base de données où vous enregistrez l'UDF gèrent ses autorisations. Voir Gérer les privilèges dans Unity Catalog pour plus d'information.

Utilisez Databricks SQL ou l'interface utilisateur du Workspace Databricks pour accorder des autorisations à un utilisateur ou à un groupe (recommandé).

Autorisations dans l'interface utilisateur du workspace

  1. Trouvez le catalogue et le schéma où votre UDF est stockée et sélectionnez l'UDF.
  2. Recherchez une option **Autorisations** dans les paramètres UDF. Ajoutez des utilisateurs ou des groupes et spécifiez le type d'accès qu'ils doivent avoir, tel que EXECUTE ou MANAGE.

Autorisations dans l'interface utilisateur de Workspace

Autorisations utilisant Databricks SQL

L’exemple suivant octroie à un utilisateur l’autorisation EXECUTE sur une fonction :

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

Pour supprimer les autorisations, utilisez la commande REVOKE comme dans l'exemple suivant :

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

Isolation de l'environnement

remarque

Les environnements d’isolation partagée nécessitent Databricks Runtime 18.1 ou une version ultérieure. Dans les versions antérieures, toutes les UDF Python Unity Catalog s’exécutent en mode d’isolation stricte.

Les UDF Python de Unity Catalog ayant le même propriétaire et la même session peuvent partager un environnement d’isolation par default. Cela améliore les performances et réduit l’utilisation de la mémoire en réduisant le nombre d’environnements distincts qui doivent être lancés.

Isolement strict

Pour vérifier qu'une UDF s'exécute toujours dans son propre environnement entièrement isolé, ajoutez la clause caractéristique STRICT ISOLATION.

La plupart des UDF n'ont pas besoin d'une isolation stricte. Les UDF de traitement de données standard bénéficient de l'environnement d'isolation partagé default et s'exécutent plus rapidement avec une consommation de mémoire inférieure.

Ajoutez la clause caractéristique STRICT ISOLATION aux UDF qui :

  • Exécutez l'entrée en tant que code à l'aide de eval(), exec() ou de fonctions similaires.
  • Écrire des fichiers dans le système de fichiers local.
  • Modifier les variables globales ou l'état du système.
  • Accéder ou modifier les variables d'environnement.

Le code suivant présente un exemple d'UDF qui doit être exécutée à l'aide de STRICT ISOLATION. Cette UDF exécute du code Python arbitraire, elle peut donc modifier l’état du système, accéder aux variables d’environnement ou écrire dans le système de fichiers local. L'utilisation de la clause STRICT ISOLATION permet d'éviter les interférences ou les fuites de données entre les fonctions UDF.

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

Définissez DETERMINISTIC si votre fonction produit des résultats cohérents

Ajoutez DETERMINISTIC à la définition de votre fonction si elle produit les mêmes sorties pour les mêmes entrées. Cela permet aux optimisations de query d'améliorer les performances.

Par default, Databricks traite les UDF Python de Unity Catalog en mode batch comme non déterministes, sauf si vous déclarez explicitement le contraire. Les exemples de fonctions non déterministes incluent la génération de valeurs aléatoires, l'accès aux heures ou dates actuelles, ou les appels d'API externes.

Voir CREATE FUNCTION (SQL, Python, Scala et Java)

UDF pour les outils d'agent

Les agents d’IA peuvent utiliser les UDF de Unity Catalog comme outils pour effectuer des tâches et exécuter une logique personnalisée.

Consultez Créer des outils d'agent à l'aide de fonctions Unity Catalog.

UDFs pour accéder aux APIs externes

Vous pouvez utiliser des UDF pour accéder aux APIs externes à partir de SQL. L'exemple suivant utilise la bibliothèque Python requests pour effectuer une requête HTTP.

remarque

Les UDF Python autorisent le trafic réseau TCP/UDP sur les ports 80, 443 et 53 lors de l'utilisation d'un compute serverless ou d'un compute configuré avec le mode d'accès standard.

SQL
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 pour la sécurité et la conformité

Utilisez les UDF Python pour implémenter des mécanismes personnalisés de tokénisation, de masquage de données, de caviardage de données ou de chiffrement.

L'exemple suivant masque l'identité d'une adresse e-mail tout en conservant la longueur et le domaine :

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

L'exemple suivant applique cette UDF dans une définition de vue dynamique :

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

Bonnes pratiques

Pour que les UDF soient accessibles à tous les utilisateurs, Databricks vous recommande de créer un catalogue et un schéma dédiés avec des contrôles d'accès appropriés.

Pour les UDF spécifiques à une équipe, utilisez un schéma dédié au sein du catalogue d'équipe pour le stockage et la gestion.

Databricks vous recommande d'inclure les informations suivantes dans la docstring de l'UDF :

  • Le numéro de version actuel
  • Un journal des modifications pour suivre les modifications entre les versions
  • L'objectif de l'UDF, les paramètres et la valeur de retour
  • Un exemple d'utilisation de l'UDF

L’exemple suivant montre une UDF qui suit les meilleures pratiques :

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

Comportement du fuseau horaire Timestamp pour les entrées ligne par ligne

Une entrée TIMESTAMP atteint une UDF Python ligne par ligne sous la forme d’une valeur datetime sans fuseau horaire en UTC. Sur le compute classique, ce comportement nécessite Databricks Runtime 18.1 ou une version ultérieure. Sur le compute serverless ainsi que sur les SQL Warehouses pro et serverless, définissez explicitement le paramètre environment_version de l’UDF sur 6 ou une version supérieure. L’objet datetime n’inclut pas de métadonnées de fuseau horaire dans son attribut tzinfo.

Les UDF Python batch Unity Catalog reçoivent des entrées timestamp dans les objets pandas.Series et n'utilisent pas ce mapping datetime.

Cette modification aligne les UDF Python de Unity Catalog avec les UDF Python optimisées pour Arrow dans Apache Spark.

Par exemple, la query suivante définit explicitement la version d'environnement 6 et le fuseau horaire de session sur UTC :

SQL
SET TIME ZONE 'UTC';

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

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

Le chemin d'exécution précédent renvoie une valeur tenant compte du fuseau horaire dans le fuseau horaire de la session. Cela s'applique au compute classique avant Databricks Runtime 18.1. Cela s'applique également au compute Serverless ainsi qu'aux SQL Warehouse Pro et Serverless lorsque vous omettez la clause ENVIRONMENT, définissez environment_version = 'None' ou sélectionnez une version antérieure à 6. Le fuseau horaire de session étant défini sur UTC, le chemin précédent produit :

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

Avec la définition présentée, le Serverless compute et les SQL Warehouse Pro et Serverless utilisent le comportement compatible avec PySpark. Le compute classique exécutant Databricks Runtime 18.1 ou une version supérieure utilise le même comportement :

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

Cette modification peut affecter les champs d’horloge ainsi que tzinfo. Pour l’instant 2024-10-23T10:30:00Z, le comportement antérieur dans une session America/Los_Angeles produit 2024-10-23 03:30:00-07:00. Le nouveau comportement produit la valeur UTC sans fuseau horaire 2024-10-23 10:30:00.

Si votre UDF repose sur des informations de fuseau horaire, rétablissez explicitement le fuseau UTC :

Python
from datetime import timezone

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

L'ajout d'informations de fuseau horaire UTC ne restaure pas les champs d'horloge locaux de la session précédente. Si votre logique a besoin de ces champs, convertissez également la valeur consciente dans le fuseau horaire de session souhaité. Par exemple :

Python
from zoneinfo import ZoneInfo

date = date.astimezone(ZoneInfo("America/Los_Angeles"))

Limitations

  • Vous pouvez définir n'importe quel nombre de fonctions Python au sein d'une UDF Python, mais toutes doivent retourner une valeur scalaire.
  • Les fonctions Python doivent gérer les valeurs NULL de manière indépendante, et toutes les correspondances de types doivent suivre les correspondances de langage Databricks SQL.
  • Si vous ne spécifiez pas de catalogue ou de schéma, Databricks enregistre les UDF Python dans le schéma actif actuel.
  • Les UDF Python s'exécutent dans un environnement sécurisé et isolé et n'ont pas accès aux systèmes de fichiers ou aux services internes.
  • Vous pouvez appeler plus de cinq UDF dans une query sur un compute classique exécutant Databricks Runtime 18.1 ou une version ultérieure. Sur le compute Serverless et sur les SQL Warehouse Pro et Serverless, chaque définition d'UDF doit définir explicitement environment_version sur 6 ou une version ultérieure.