Écriture d’une UDTF en Python

Dans ce chapitre :

Vous pouvez implémenter un gestionnaire de fonction de table définie par l’utilisateur (UDTF) en Python. Ce code de gestionnaire s’exécute lorsque l’UDTF est appelée. Cette rubrique décrit comment implémenter un gestionnaire en Python et créer l’UDTF.

Une UDTF est une fonction définie par l’utilisateur (UDF) qui renvoie des résultats sous forme tabulaire. Pour en savoir plus sur les gestionnaires UDF implémentés en Python, voir Création d’UDFs Python. Pour plus d’informations générales sur les UDFs, voir Vue d’ensemble des fonctions définies par l’utilisateur.

Dans le gestionnaire d’une UDTF, vous pouvez traiter les lignes d’entrée (voir Traitement des lignes dans cette rubrique). Vous pouvez également avoir une logique qui s’exécute pour chaque partition d’entrée (voir Traitement des partitions dans cette rubrique).

Lorsque vous créez une UDTF Python, vous effectuez les opérations suivantes :

  1. Implémentez une classe avec des méthodes que Snowflake invoquera lorsque l’UDTF est appelée.

    Pour plus de détails, voir Implémentation d’un gestionnaire dans cette rubrique.

  2. Créez l’UDTF en SQL avec la commande CREATE FUNCTION, en spécifiant votre classe comme gestionnaire. Quand vous créez l’UDTF, vous spécifiez :

    • Les types de données des paramètres d’entrée de l’UDTF.

    • Les types de données des colonnes renvoyées par l’UDTF.

    • Le code à exécuter en tant que gestionnaire lorsque l’UDTF est appelée.

    • La langue dans laquelle le gestionnaire est implémenté.

    Pour en savoir plus sur la syntaxe, voir Création de l’UDTF avec CREATE FUNCTION dans cette rubrique.

Vous pouvez appeler une UDF ou une UDTF comme décrit dans Appel d’une UDF.

Note

Les fonctions de table (UDTFs) ont une limite de 500 arguments d’entrée et 500 colonnes de sortie.

Snowflake prend actuellement en charge l’écriture d’UDTFs Java dans les versions suivantes de Python :

  • 3,8

  • 3,9

  • 3,10

  • 3,11

Dans votre instruction CREATE FUNCTION, définissez runtime_version comme étant la version souhaitée.

Implémentation d’un gestionnaire

Vous implémentez une classe de gestionnaire pour traiter les valeurs des arguments d’UDTF dans des résultats tabulaires et gérer les entrées partitionnées. Pour un exemple de classe de gestionnaire, voir Exemple de classe de gestionnaire dans cette rubrique.

Lorsque vous créez l’UDTF avec CREATE FUNCTION, vous spécifiez cette classe comme gestionnaire de l’UDTF. Pour en savoir plus sur le code SQL permettant de créer la fonction, voir Création de l’UDTF avec CREATE FUNCTION dans cette rubrique.

Une classe de gestionnaire implémente les méthodes que Snowflake invoquera lorsque l’UDTF est appelée. Cette classe contient la logique de l’UDTF.

Méthode

Exigence

Description

Méthode __init__

Facultatif

Initialise l’état pour le traitement d’état des partitions d’entrée. Pour plus d’informations, voir Initialisation du gestionnaire dans cette rubrique.

Méthode process

Obligatoire

Traite chaque ligne d’entrée, en retournant une valeur tabulaire sous forme de tuples. Snowflake invoque cette méthode, en transmettant les entrées des arguments d’UDTF. Pour plus d’informations, voir Définition d’une méthode process dans cette rubrique.

Méthode end_partition

Facultatif

Finalise le traitement des partitions d’entrée, en renvoyant une valeur tabulaire sous forme de tuples. Pour plus d’informations, voir Finalisation du traitement des partitions dans cette rubrique.

L’émission d’une exception à partir de n’importe quelle méthode de la classe du gestionnaire entraîne l’arrêt du traitement. La requête qui a appelé l’UDTF échoue avec un message d’erreur.

Note

Si votre code ne répond pas aux exigences décrites ici, la création ou l’exécution de l’UDTF peut échouer. Snowflake détectera les violations lorsque l’instruction CREATE FUNCTION sera exécutée.

Exemple de classe de gestionnaire

Le code de l’exemple suivant crée une UDTF dont la classe de gestionnaire traite les lignes d’une partition. La méthode process traite chaque ligne d’entrée et renvoie une ligne contenant le coût total d’une vente d’action. Après avoir traité les lignes de la partition, elle renvoie (à partir de sa méthode end_partition) le total de toutes les ventes incluses dans la partition.

create or replace function stock_sale_sum(symbol varchar, quantity number, price number(10,2))
returns table (symbol varchar, total number(10,2))
language python
runtime_version=3.8
handler='StockSaleSum'
as $$
class StockSaleSum:
    def __init__(self):
        self._cost_total = 0
        self._symbol = ""

    def process(self, symbol, quantity, price):
      self._symbol = symbol
      cost = quantity * price
      self._cost_total += cost
      yield (symbol, cost)

    def end_partition(self):
      yield (self._symbol, self._cost_total)
$$;
Copy

Le code de l’exemple suivant appelle l’UDF précédente, en transmettant les valeurs des colonnes symbol, quantity, et price de la table stocks_table. Pour plus d’informations sur l’appel d’une UDTF, reportez-vous à Appel d’une UDF.

select stock_sale_sum.symbol, total
  from stocks_table, table(stock_sale_sum(symbol, quantity, price) over (partition by symbol));
Copy

Initialisation du gestionnaire

Vous pouvez éventuellement implémenter une méthode __init__ dans votre classe de gestionnaire que Snowflake invoquera avant que le gestionnaire ne commence à traiter les lignes. Par exemple, vous pouvez utiliser cette méthode pour établir un état spécifique à la partition pour le gestionnaire. Votre méthode __init__ peut ne pas produire de lignes de sortie.

La signature de la méthode doit être de la forme suivante :

def __init__(self):
Copy

Par exemple, vous pourriez vouloir :

  • Initialise l’état d’une partition, puis utilise cet état dans les méthodes process et end_partition.

  • Exécutez une initialisation de longue durée qui doit être effectuée une seule fois par partition plutôt qu’une fois par ligne.

Note

Vous pouvez également exécuter la logique une fois avant le début du traitement des partitions en incluant ce code en dehors de la classe du gestionnaire, par exemple avant la déclaration de la classe.

Pour plus d’informations sur le traitement des partitions, voir Traitement des partitions dans cette rubrique.

Si vous utilisez une méthode __init__ n’oubliez pas que __init__ :

  • Ne peut prendre que self comme argument.

  • Impossible de produire de lignes de sortie. Utilisez l’implémentation de votre méthode process pour cela.

  • Est invoquée une fois pour chaque partition, et avant que la méthode process soit invoquée.

Traitement des lignes

Implémentez une méthode process que Snowflake invoquera pour chaque ligne d’entrée.

Définition d’une méthode process

Définissez une méthode process qui reçoit comme valeurs les UDTF arguments convertis à partir de types SQL, renvoyant des données que Snowflake utilisera pour créer la valeur de retour tabulaire de l’UDTF.

La signature de la méthode doit être de la forme suivante :

def process(self, *args):
Copy

Votre méthode process doit :

  • Avoir un paramètre self.

  • Déclarer les paramètres de la méthode correspondant aux paramètres de l’UDTF.

    Les noms des paramètres des méthodes ne doivent pas nécessairement correspondre aux noms des paramètres de l’UDTF, mais les paramètres des méthodes doivent être déclarés dans le même ordre que les paramètres de l’UDTF.

    Lorsque vous transmettez des valeurs d’arguments de l’UDTF à votre méthode, Snowflake convertit les valeurs des types SQL en types Python que vous utilisez dans la méthode. Pour plus d’informations sur la manière dont Snowflake établit une correspondance entre SQL et les types de données Python, voir Mappages des types de données SQL-Python.

  • Donne un ou plusieurs tuples (ou renvoie un itérable contenant des tuples), dans lequel la séquence de tuples correspond à la séquence de colonnes de valeurs de retour de l’UDTF.

    Les éléments du tuple doivent apparaître dans le même ordre que les colonnes de la valeur de retour UDTF sont déclarées. Pour plus d’informations, voir Renvoyer une valeur dans cette rubrique.

    Snowflake convertira les valeurs des types Python en types SQL requis par la déclaration UDTF. Pour plus d’informations sur la manière dont Snowflake établit une correspondance entre SQL et les types de données Python, voir Mappages des types de données SQL-Python.

Si une méthode de la classe du gestionnaire lève une exception, le traitement s’arrête. La requête qui a appelé l’UDTF échoue avec un message d’erreur. Si la méthode process renvoie None, le traitement s’arrête. (La méthode end_partition est toujours invoquée même si la méthode process renvoie None).

Exemple de méthode de traitement

L’exemple suivant présente une classe de gestionnaire StockSale avec une méthode process qui traite trois arguments UDTF (symbol, quantity, et price), et renvoie une seule ligne avec deux colonnes (symbol et total). Notez que les paramètres de la méthode process sont déclarés dans le même ordre que les paramètres stock_sale. Les arguments de l’instruction yield de la méthode process sont dans le même ordre que les colonnes déclarées dans la clause stock_sale RETURNS TABLE.

create or replace function stock_sale(symbol varchar, quantity number, price number(10,2))
returns table (symbol varchar, total number(10,2))
language python
runtime_version=3.8
handler='StockSale'
as $$
class StockSale:
    def process(self, symbol, quantity, price):
      cost = quantity * price
      yield (symbol, cost)
$$;
Copy

Le code de l’exemple suivant appelle l’UDF précédente, en transmettant les valeurs des colonnes symbol, quantity, et price de la table stocks_table.

select stock_sale.symbol, total
  from stocks_table, table(stock_sale(symbol, quantity, price) over (partition by symbol));
Copy

Renvoyer une valeur

Lorsque vous renvoyez des lignes de sortie, vous pouvez utiliser soit yield soit return (mais pas les deux) pour renvoyer des tuples avec la valeur tabulaire. Si la méthode renvoie ou produit None, le traitement de la ligne en cours s’arrête.

  • Lorsque vous utilisez yield, exécutez une instruction yield distincte pour chaque ligne de sortie. Il s’agit de la meilleure pratique, car l’évaluation paresseuse qui accompagne yield permet un traitement plus efficace et peut contribuer à éviter les dépassements de délai d’expiration.

    Chaque élément du tuple devient une valeur de colonne dans le résultat renvoyé par l’UDTF. L’ordre des arguments yield doit correspondre à l’ordre des colonnes déclarées pour la valeur de retour dans la clause RETURNS TABLE de CREATE FUNCTION.

    Le code de l’exemple suivant renvoie des valeurs représentant deux rangées.

    def process(self, symbol, quantity, price):
      cost = quantity * price
      yield (symbol, cost)
      yield (symbol, cost)
    
    Copy

    Notez que, comme l’argument de rendement est un tuple, vous devez inclure une virgule de fin lorsque vous passez une seule valeur dans le tuple, comme dans l’exemple suivant.

    yield (cost,)
    
    Copy
  • En utilisant return, renvoyez un itérable avec des tuples.

    Chaque valeur d’un tuple devient une valeur de colonne dans le résultat renvoyé par l’UDTF. L’ordre des valeurs des colonnes dans un tuple doit correspondre à l’ordre des colonnes déclarées pour la valeur de retour dans la clause RETURNS TABLE de CREATE FUNCTION.

    Le code de l’exemple suivant renvoie deux lignes, chacune avec deux colonnes : symbole et total.

    def process(self, symbol, quantity, price):
      cost = quantity * price
      return [(symbol, cost), (symbol, cost)]
    
    Copy

Ignorer des lignes

Pour ignorer une ligne d’entrée et traiter la ligne suivante (par exemple, lorsque vous validez les lignes d’entrée), faites en sorte que la méthode process renvoie l’un des éléments suivants :

  • Lorsque vous utilisez return, vous devez retourner None, une liste contenant None, ou une liste vide pour ignorer la ligne.

  • Lorsque vous utilisez yield, retournez None pour ignorer une ligne.

    Notez que si vous avez plusieurs appels à yield, tout appel après un appel qui renvoie None sera ignoré par Snowflake.

Le code de l’exemple suivant renvoie uniquement les lignes pour lesquelles number est un nombre entier positif. Si number n’est pas positif, la méthode renvoie None vide pour ignorer la ligne actuelle et poursuivre le traitement de la ligne suivante.

def process(self, number):
  if number < 1:
    yield None
  else:
    yield (number)
Copy

Traitement avec et sans état

Vous pouvez implémenter le gestionnaire pour traiter les lignes en tenant compte des partitions ou pour les traiter simplement ligne par ligne.

  • Dans le traitement en tenant compte des partitions, le gestionnaire inclut du code pour gérer l’état spécifique à la partition. Cela comprend une méthode __init__ qui s’exécute au début du traitement de la partition et une méthode end_partition que Snowflake invoque après avoir traité la dernière ligne de la partition. Pour plus d’informations, voir Traitement des partitions dans cette rubrique.

  • Dans le traitement tenant compte de la partition, le gestionnaire s’exécute sans état, en ignorant les limites des partitions.

    Pour que le gestionnaire s’exécute de cette façon, il ne faut pas inclure de méthode __init__ ou end_partition.

Traitement des partitions

Vous pouvez traiter les partitions en entrée avec du code qui s’exécute par partition (par exemple pour gérer l’état) ainsi que du code qui s’exécute pour chaque ligne de la partition.

Note

Pour plus d’informations sur la spécification des partitions lors de l’appel d’une UDTF, reportez-vous à Fonctions et partitions des tables.

Lorsqu’une requête inclut des partitions, elle agrège les lignes en utilisant une valeur spécifiée, telle que la valeur d’une colonne. Les lignes agrégées que votre gestionnaire reçoit sont dites partitionnées par cette valeur. Votre code peut traiter ces partitions et leurs lignes de façon à ce que le traitement de chaque partition comprenne un état spécifique à la partition.

Le code de l’exemple SQL suivant demande des informations sur les ventes d’actions. Il exécute une UDTF stock_sale_sum dont l’entrée est partitionnée par la valeur de la colonne symbol.

select stock_sale_sum.symbol, total
  from stocks_table, table(stock_sale_sum(symbol, quantity, price) over (partition by symbol));
Copy

Gardez à l’esprit que même lorsque les lignes entrantes sont partitionnées, votre code peut ignorer la séparation des partitions et traiter simplement les lignes. Par exemple, vous pouvez omettre le code conçu pour gérer l’état de la partition, tel que la méthode __init__ et la méthode end_partition d’une classe de gestionnaire, et n’implémenter que la méthode process. Pour plus d’informations, voir Traitement avec et sans état dans cette rubrique.

Pour traiter chaque partition en tant qu’unité, vous devez :

  • Implémentez une méthode __init__ de classe de gestionnaire dans laquelle vous initialiserez le traitement de la partition.

    Pour plus d’informations, voir Initialisation du gestionnaire dans cette rubrique.

  • Incluez un code tenant compte des partitions lors du traitement de chaque ligne avec la méthode process.

    Pour plus d’informations sur le traitement des lignes, voir Traitement des lignes dans cette rubrique.

  • Implémentez une méthode end_partition pour finaliser le traitement de la partition.

    Pour plus d’informations, voir Finalisation du traitement des partitions dans cette rubrique.

Les paragraphes suivants décrivent la séquence des invocations de votre gestionnaire lorsque vous avez inclus du code conçu pour être exécuté par partition.

  1. Lorsque le traitement d’une partition commence, et avant que la première ligne n’ait été traitée, Snowflake utilise la méthode __init__ de votre classe de gestionnaire pour créer une instance de la classe.

    Ici, vous pouvez établir l’état de la partition spécifique. Par exemple, vous pouvez initialiser une variable d’instance pour contenir une valeur calculée à partir de lignes de la partition.

  2. Pour chaque ligne de la partition, Snowflake invoque la méthode process.

    Chaque fois que la méthode s’exécute, elle peut apporter des modifications aux valeurs de l’état. Par exemple, vous pouvez demander à la méthode process de mettre à jour la valeur de la variable d’instance.

  3. Une fois que votre code a traité la dernière ligne de la partition, Snowflake invoque votre méthode end_partition.

    À partir de cette méthode, vous pouvez renvoyer des lignes de sortie contenant une valeur de niveau de partition que vous souhaitez renvoyer. Par exemple, vous pouvez renvoyer la valeur de la variable d’instance que vous avez mise à jour au fur et à mesure que vous traitez les lignes de la partition.

    Votre méthode end_partition ne recevra aucun argument de Snowflake, qui l’invoquera simplement après avoir traité la dernière ligne de la partition.

Finalisation du traitement des partitions

Vous pouvez éventuellement implémenter une méthode end_partition dans votre classe de gestionnaire que Snowflake invoquera après avoir traité toutes les lignes d’une partition. Avec cette méthode, vous pouvez exécuter le code pour une partition après que toutes les lignes de la partition aient été traitées. Votre méthode end_partition peut produire des lignes de sortie, par exemple pour renvoyer les résultats d’un calcul à l’échelle de la partition. Pour plus d’informations, voir Traitement des partitions dans cette rubrique.

La signature de la méthode doit être de la forme suivante :

def end_partition(self):
Copy

Snowflake attend de l’implémentation de votre méthode end_partition ce qui suit :

  • Elle ne doit pas être statique.

  • Elle ne peut avoir d’autres paramètres que self.

  • Au lieu de renvoyer une valeur tabulaire, elle peut produire une liste vide ou None.

Note

Bien que Snowflake prenne en charge les grandes partitions avec des délais d’expiration définis pour les traiter avec succès, les partitions particulièrement grandes peuvent entraîner des expirations (par exemple lorsque end_partition prend trop de temps à se terminer). Veuillez contacter le support Snowflake si vous avez besoin d’ajuster le seuil d’expiration pour des scénarios d’utilisation spécifiques.

Exemple de traitement des partitions

Le code de l’exemple suivant calcule le coût total payé sur l’ensemble des achats pour une action en calculant d’abord le coût par achat et en additionnant les achats (dans la méthode process). Le code renvoie le total dans la méthode end_partition.

Pour un exemple d’une UDTF qui inclut ce gestionnaire, ainsi que l’appel de l’UDTF, reportez-vous à Exemple de classe de gestionnaire.

class StockSaleSum:
  def __init__(self):
    self._cost_total = 0
    self._symbol = ""

  def process(self, symbol, quantity, price):
    self._symbol = symbol
    cost = quantity * price
    self._cost_total += cost
    yield (symbol, cost)

  def end_partition(self):
    yield (self._symbol, self._cost_total)
Copy

Lors du traitement des partitions, gardez à l’esprit les points suivants :

  • Votre code peut gérer des partitions qui ne sont pas explicitement spécifiées dans un appel à l’UDTF. Même lorsqu’un appel à l’UDTF n’inclut pas de clause PARTITION BY, Snowflake partitionne les données de manière implicite.

  • Votre méthode process recevra les données des lignes dans l’ordre spécifié par la clause ORDER BY de la partition, le cas échéant.

Exemples

Utilisation d’un paquet importé

Vous pouvez utiliser les paquets Python qui sont inclus dans une liste de packages tiers d’Anaconda disponibles dans Snowflake. Pour spécifier ces paquets en tant que dépendances dans l’UDTF, utilisez la clause PACKAGES dans CREATE FUNCTION.

Vous pouvez découvrir la liste des paquets inclus en exécutant la commande SQL suivante dans Snowflake :

select * from information_schema.packages where language = 'python';
Copy

Pour plus d’informations, voir Utilisation de paquets tiers et Création d’UDFs Python.

Le code de l’exemple suivant utilise une fonction du paquet NumPy (Numerical Python) pour calculer le prix moyen par action à partir d’un tableau d’achats d’actions, chacune ayant un prix par action différent.

create or replace function stock_sale_average(symbol varchar, quantity number, price number(10,2))
returns table (symbol varchar, total number(10,2))
language python
runtime_version=3.8
packages = ('numpy')
handler='StockSaleAverage'
as $$
import numpy as np

class StockSaleAverage:
    def __init__(self):
      self._price_array = []
      self._quantity_total = 0
      self._symbol = ""

    def process(self, symbol, quantity, price):
      self._symbol = symbol
      self._price_array.append(float(price))
      cost = quantity * price
      yield (symbol, cost)

    def end_partition(self):
      np_array = np.array(self._price_array)
      avg = np.average(np_array)
      yield (self._symbol, avg)
$$;
Copy

Le code de l’exemple suivant appelle l’UDF précédente, en transmettant les valeurs des colonnes symbol, quantity, et price de la table stocks_table. Pour plus d’informations sur l’appel d’une UDTF, reportez-vous à Appel d’une UDF.

select stock_sale_average.symbol, total
  from stocks_table,
  table(stock_sale_average(symbol, quantity, price)
    over (partition by symbol));
Copy

Exécution de tâches simultanées à l’aide de processus de travail

Vous pouvez exécuter des tâches simultanées à l’aide de processus de travail Python. Cela peut s’avérer utile lorsque vous devez exécuter des tâches parallèles qui tirent parti de plusieurs cœurs CPU sur les nœuds de l’entrepôt.

Note

Snowflake vous recommande de ne pas utiliser le module de multitraitement intégré à Python.

Pour contourner les cas où le Python Global Interpreter Lock empêche une approche multitâche de s’étendre à tous les cœurs CPU, vous pouvez exécuter des tâches concurrentes à l’aide de processus de travail distincts, plutôt que de threads.

Vous pouvez le faire sur des entrepôts Snowflake en utilisant la classe Parallel de la bibliothèque joblib comme dans l’exemple suivant.

CREATE OR REPLACE FUNCTION joblib_multiprocessing_udtf(i INT)
  RETURNS TABLE (result INT)
  LANGUAGE PYTHON
  RUNTIME_VERSION = 3.8
  HANDLER = 'JoblibMultiprocessing'
  PACKAGES = ('joblib')
AS $$
import joblib
from math import sqrt

class JoblibMultiprocessing:
  def process(self, i):
    pass

  def end_partition(self):
    result = joblib.Parallel(n_jobs=-1)(joblib.delayed(sqrt)(i ** 2) for i in range(10))
    for r in result:
      yield (r, )
$$;
Copy

Note

Le backend par défaut utilisé pour joblib.Parallel diffère entre les entrepôts standards de Snowflake et les entrepôts optimisés pour Snowpark.

  • Valeur par défaut de l’entrepôt standard : threading

  • Valeur par défaut de l’entrepôt optimisé pour Snowpark : loky (multitraitement)

Vous pouvez remplacer le paramètre de backend par défaut en appelant la fonction joblib.parallel_backend comme dans l’exemple suivant.

import joblib
joblib.parallel_backend('loky')
Copy

Création de l’UDTF avec CREATE FUNCTION

Vous créez une UDTF avec SQL en utilisant la commande CREATE FUNCTION, en spécifiant le code que vous avez écrit comme gestionnaire. Pour la référence de la commande, voir CREATE FUNCTION.

Utilisez la syntaxe suivante pour créer une UDTF.

CREATE OR REPLACE FUNCTION <name> ( [ <arguments> ] )
  RETURNS TABLE ( <output_column_name> <output_column_type> [, <output_column_name> <output_column_type> ... ] )
  LANGUAGE PYTHON
  [ IMPORTS = ( '<imports>' ) ]
  RUNTIME_VERSION = 3.8
  [ PACKAGES = ( '<package_name>' [, '<package_name>' . . .] ) ]
  [ TARGET_PATH = '<stage_path_and_file_name_to_write>' ]
  HANDLER = '<handler_class>'
  [ AS '<python_code>' ]
Copy

Pour associer le code du gestionnaire que vous avez écrit avec l’UDTF, vous faites ce qui suit lors de l’exécution de CREATE FUNCTION :

  • Dans RETURNS TABLE, spécifiez les colonnes de sortie dans les paires nom de colonne et type.

  • Définissez LANGUAGE sur PYTHON.

  • Définissez la valeur de la clause IMPORTS sur le chemin et le nom de la classe du gestionnaire si la classe se trouve dans un emplacement externe, par exemple sur une zone de préparation.

    Pour plus d’informations, voir Création d’UDFs 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,8

    • 3,9

    • 3,10

    • 3,11

  • Définissez la valeur de la clause PACKAGES sur le nom d’un ou plusieurs paquets, le cas échéant, requis par la classe du gestionnaire.

    Pour plus d’informations, voir Utilisation de paquets tiers et Création d’UDFs Python.

  • Définissez la valeur de la clause HANDLER comme étant le nom de la classe du gestionnaire.

    Lorsque vous associez un code de gestionnaire Python à une UDTF, vous pouvez soit inclure le code en ligne, soit y faire référence à un emplacement sur une zone de préparation Snowflake. La valeur de HANDLER est sensible à la casse et doit correspondre au nom de la classe Python.

    Pour plus d’informations, voir UDFs avec du code en ligne vs. UDFs avec du code téléchargé à partir d’une zone de préparation.

    Important

    Pour une UDF scalaire Python, la valeur de la clause HANDLER contient le nom de la méthode.

    Pour une UDTF Python, la valeur de la clause HANDLER contient le nom de la classe, mais pas un nom de méthode.

    La raison de cette différence est que pour une UDF scalaire Python, le nom de la méthode de gestion est choisi par l’utilisateur et n’est donc pas connu à l’avance par Snowflake, mais pour une UDTF Python, les noms des méthodes (par exemple end_partition) sont connus, car ils doivent correspondre aux noms spécifiés par Snowflake.

  • La clause AS '<python_code>' est requise si le code du gestionnaire est spécifié en ligne avec CREATE FUNCTION.