É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 :
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.
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 |
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 |
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 |
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)
$$;
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));
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):
Par exemple, vous pourriez vouloir :
Initialise l’état d’une partition, puis utilise cet état dans les méthodes
process
etend_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):
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)
$$;
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));
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 instructionyield
distincte pour chaque ligne de sortie. Il s’agit de la meilleure pratique, car l’évaluation paresseuse qui accompagneyield
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)
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,)
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)]
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 retournerNone
, une liste contenantNone
, ou une liste vide pour ignorer la ligne.Lorsque vous utilisez
yield
, retournezNone
pour ignorer une ligne.Notez que si vous avez plusieurs appels à
yield
, tout appel après un appel qui renvoieNone
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)
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éthodeend_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__
ouend_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));
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.
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.
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.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):
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)
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';
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)
$$;
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));
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, )
$$;
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')
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>' ]
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.