CrĂ©ation d’UDFs Python¶

Cette rubrique montre comment crĂ©er et installer une UDF Python (fonction dĂ©finie par l’utilisateur).

Dans ce chapitre :

Écrire le code Python¶

Écriture le module et la fonction Python¶

Écrivez un module qui suit les spĂ©cifications ci-dessous :

  • DĂ©finissez le module. Un module est un fichier contenant des dĂ©finitions et des instructions Python.

  • DĂ©finissez une fonction Ă  l’intĂ©rieur du module.

  • Si la mĂ©thode accepte des arguments, chaque argument doit ĂȘtre l’un des types de donnĂ©es spĂ©cifiĂ©s dans la colonne Python Data Type de la table SQL-Python Type Mappings.

    Les arguments de fonction sont liĂ©s par leur position, et non par leur nom. Le premier argument transmis Ă  l’UDF est le premier argument reçu par la mĂ©thode Python.

  • SpĂ©cifiez une valeur de retour appropriĂ©e. Comme une UDF Python doit ĂȘtre une fonction scalaire, elle doit renvoyer une valeur Ă  chaque fois qu’elle est appelĂ©e. Le type de la valeur de retour doit ĂȘtre l’un des types de donnĂ©es spĂ©cifiĂ©s dans la colonne Python Data Type de la table SQL-Python Type Mappings. Le type de la valeur de retour doit ĂȘtre compatible avec le type de donnĂ©es SQL spĂ©cifiĂ© dans la clause RETURNS de l’instruction CREATE FUNCTION.

  • Votre module peut contenir plus d’une fonction. La fonction qui est appelĂ©e par Snowflake peut appeler d’autres fonctions dans le mĂȘme module ou dans d’autres modules.

  • Votre fonction (et toute fonction appelĂ©e par votre fonction) doit respecter les contraintes Snowflake imposĂ©es pour les UDFs Python.

Note

Les UDFs Python vectorisĂ©es vous permettent de dĂ©finir des fonctions Python qui reçoivent des lots de lignes d’entrĂ©e sous forme de DataFrames Pandas et renvoient des lots de rĂ©sultats sous forme de tableaux ou de sĂ©ries Pandas. Pour plus d’informations, voir UDFs Python vectorisĂ©es.

Création de la fonction dans Snowflake¶

Vous devez exĂ©cuter une instruction CREATE FUNCTION pour spĂ©cifier :

  • Nom Ă  utiliser pour l’UDF.

  • Le nom de la fonction Python Ă  appeler lorsque l’UDF Python est appelĂ©e.

Le nom de l’UDF ne doit pas nĂ©cessairement correspondre au nom de la fonction du gestionnaire Ă©crit en Python. La clause HANDLER dans l’instruction CREATE FUNCTION associe le nom de l’UDF Ă  la fonction Python.

Pour choisir un nom pour l’UDF, reportez-vous Ă  Nommage et surcharge de procĂ©dures et d’UDFs :

Dans le corps de l’instruction CREATE FUNCTION, les arguments de la fonction sont liĂ©s Ă  la position, pas au nom. Le premier argument dĂ©clarĂ© dans l’instruction CREATE FUNCTION est le premier argument transmis Ă  la fonction Python.

Pour plus d’informations sur les types de donnĂ©es des arguments, voir Mappages des types de donnĂ©es SQL-Python.

DĂ©finissez runtime_version sur la version de l’environnement d’exĂ©cution Python requise par votre code. Les versions de Python prises en charge sont les suivantes :

  • 3,9

  • 3,10

  • 3,11

  • 3,12

Les UDFs avec du code en ligne vs. les UDFs avec du code tĂ©lĂ©chargĂ© Ă  partir d’une zone de prĂ©paration¶

Le code d’une UDF Python peut ĂȘtre spĂ©cifiĂ© de l’une des maniĂšres suivantes :

  • TĂ©lĂ©chargĂ© Ă  partir d’une zone de prĂ©paration : l’instruction CREATE FUNCTION spĂ©cifie l’emplacement d’un code source Python existant dans une zone de prĂ©paration.

  • En ligne : l’instruction CREATE FUNCTION spĂ©cifie le code source Python.

CrĂ©ation d’une UDF Python en ligne¶

Pour une UDF en ligne, vous fournissez le code source Python dans le cadre de l’instruction CREATE FUNCTION.

Par exemple, l’instruction suivante crĂ©e une UDF Python en ligne qui ajoute +1 Ă  un nombre entier donnĂ© :

CREATE OR REPLACE FUNCTION addone(i INT)
  RETURNS INT
  LANGUAGE PYTHON
  RUNTIME_VERSION = '3.9'
  HANDLER = 'addone_py'
AS $$
def addone_py(i):
 return i+1
$$;
Copy

Le code source Python est spĂ©cifiĂ© dans la clause AS. Le code source peut ĂȘtre dĂ©limitĂ© soit de guillemets simples, soit d’une paire de signes de dollar ($$). L’utilisation du double signe dollar est gĂ©nĂ©ralement plus facile si le code source contient des guillemets simples intĂ©grĂ©s.

Appelez l’UDF :

SELECT addone(10);
Copy

Voici la sortie :

+------------+
| ADDONE(10) |
|------------|
|         11 |
+------------+

Le code source Python peut contenir plus d’un module, et plus d’une fonction dans un module, donc la clause HANDLER spĂ©cifie le module et la fonction Ă  appeler.

Une UDF Python en ligne peut appeler du code dans les modules qui sont inclus dans la clause IMPORTS.

Pour plus de dĂ©tails sur la syntaxe de l’instruction CREATE FUNCTION, voir CREATE FUNCTION.

Pour plus d’exemples, voir Exemples d’UDF Python en ligne.

CrĂ©ation d’une UDF Python avec du code tĂ©lĂ©chargĂ© Ă  partir d’une zone de prĂ©paration¶

Les instructions suivantes crĂ©ent une simple UDF Python en utilisant du code tĂ©lĂ©chargĂ© Ă  partir d’une zone de prĂ©paration. La zone de prĂ©paration hĂ©bergeant le fichier doit ĂȘtre lisible par le propriĂ©taire de l’UDF. En outre, les fichiers ZIP doivent ĂȘtre autonomes et ne pas dĂ©pendre de scripts d’installation supplĂ©mentaires pour ĂȘtre exĂ©cutĂ©s.

CrĂ©ez un fichier Python nommĂ© sleepy.py qui contient votre code source :

def snore(n):   # return a series of n snores
  result = []
  for a in range(n):
    result.append("Zzz")
  return result
Copy

Lancez SnowSQL (CLI client) et utilisez la commande PUT pour copier le fichier du systĂšme de fichiers local vers une zone de prĂ©paration utilisateur par dĂ©faut, nommĂ©e @~. (La commande PUT ne peut pas ĂȘtre exĂ©cutĂ©e par la GUI Snowflake.)

put
file:///Users/Me/sleepy.py
@~/
auto_compress = false
overwrite = true
;
Copy

Si vous supprimez ou renommez le fichier, vous ne pouvez plus appeler l’UDF. Si vous devez mettre Ă  jour votre fichier, faites-le pendant qu’aucun appel Ă  l’UDF ne soit possible. Si l’ancien fichier .jar se trouve toujours dans la zone de prĂ©paration, la commande PUT doit inclure la clause OVERWRITE=TRUE.

CrĂ©ez l’UDF. Le gestionnaire spĂ©cifie le module et la fonction.

CREATE OR REPLACE FUNCTION dream(i INT)
  RETURNS VARIANT
  LANGUAGE PYTHON
  RUNTIME_VERSION = '3.9'
  HANDLER = 'sleepy.snore'
  IMPORTS = ('@~/sleepy.py')
Copy

Appelez l’UDF :

SELECT dream(3);
Copy
+----------+
| DREAM(3) |
|----------|
| [        |
|   "Zzz", |
|   "Zzz", |
|   "Zzz"  |
| ]        |
+----------+

SpĂ©cification de fichiers d’importation multiples¶

Voici un exemple de la façon de spĂ©cifier plusieurs fichiers d’importation.

CREATE OR REPLACE FUNCTION multiple_import_files(s STRING)
  RETURNS STRING
  LANGUAGE PYTHON
  RUNTIME_VERSION = 3.9
  IMPORTS = ('@python_udf_dep/bar/python_imports_a.zip', '@python_udf_dep/foo/python_imports_b.zip')
  HANDLER = 'compute'
AS $$
def compute(s):
  return s
$$;
Copy

Note

Les noms des fichiers d’importation spĂ©cifiĂ©s doivent ĂȘtre diffĂ©rents. Par exemple, ceci ne fonctionnera pas : imports=('@python_udf_dep/bar/python_imports.zip', '@python_udf_dep/foo/python_imports.zip').

Accorder des privilÚges sur la fonction¶

Pour qu’un rĂŽle autre que le propriĂ©taire de la fonction puisse appeler la fonction, le propriĂ©taire doit accorder les privilĂšges appropriĂ©s au rĂŽle.

Les instructions GRANT pour une UDF Python sont essentiellement identiques aux instructions GRANT pour d’autres UDFs, comme les UDFs JavaScript.

Par exemple :

GRANT USAGE ON FUNCTION my_python_udf(number, number) TO my_role;
Copy