Exemples de gestionnaires dâUDF Python¶
Cette rubrique comprend des exemples simples de code de gestionnaire dâUDF Ă©crits en Python.
Pour obtenir des informations sur lâutilisation de Python pour crĂ©er un gestionnaire dâUDF, reportez-vous Ă 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,9
3,10
3,11
3,12
Importation dâun paquet dans un gestionnaire en ligne¶
Une sĂ©lection de paquets tiers dâAnaconda est disponible. Pour plus dâinformations, voir Utilisation de paquets tiers.
Note
Avant que vous puissiez utiliser les paquets fournis par Anaconda, lâadministrateur de votre organisation Snowflake doit accepter les conditions de tiers externes de Snowflake. Pour plus dâinformations, voir Utilisation de paquets tiers Ă partir dâAnaconda.
Le code suivant montre comment importer des paquets et renvoyer leurs versions.
CrĂ©ez lâUDF :
CREATE OR REPLACE FUNCTION py_udf()
RETURNS VARIANT
LANGUAGE PYTHON
RUNTIME_VERSION = 3.9
PACKAGES = ('numpy','pandas','xgboost==1.5.0')
HANDLER = 'udf'
AS $$
import numpy as np
import pandas as pd
import xgboost as xgb
def udf():
return [np.__version__, pd.__version__, xgb.__version__]
$$;
Appelez lâUDF :
SELECT py_udf();
+-------------+
| PY_UDF() |
|-------------|
| [ |
| "1.19.2", |
| "1.4.0", |
| "1.5.0" |
| ] |
+-------------+
Vous pouvez utiliser le mot-clé PACKAGES pour spécifier les versions des paquets comme suit :
Sans version (par exemple
numpy
)Avec une version exacte (par exemple,
numpy==1.25.2
)Contrainte à un préfixe de version en utilisant des caractÚres génériques (par exemple
numpy==1.*
)Contrainte Ă une plage de versions (par exemple
numpy>=1.25
)Contrainte par plusieurs spécificateurs de version (par exemple
numpy>=1.25,<2
) de sorte quâun paquet qui satisfait Ă tous les spĂ©cificateurs de version sera sĂ©lectionnĂ©.
Note
Lâutilisation de plusieurs opĂ©rateurs de plage (par exemple numpy>=1.25,<2
) nâest pas prise en charge dans les politiques de paquets, mais vous pouvez les utiliser lors de la crĂ©ation dâUDF, dâUDTF et de procĂ©dures stockĂ©es Python.
Voici un exemple dâutilisation du caractĂšre gĂ©nĂ©rique *
pour contraindre un paquet à un préfixe de version.
CREATE OR REPLACE FUNCTION my_udf()
RETURNS STRING
LANGUAGE PYTHON
PACKAGES = ('numpy==1.*')
RUNTIME_VERSION = 3.10
HANDLER = 'echo'
AS $$
def echo():
return 'hi'
$$;
Cet exemple montre comment contraindre un paquet Ă ĂȘtre supĂ©rieur ou Ă©gal Ă une version spĂ©cifiĂ©e.
CREATE OR REPLACE FUNCTION my_udf()
RETURNS STRING
LANGUAGE PYTHON
PACKAGES = ('numpy>=1.2')
RUNTIME_VERSION = 3.10
HANDLER = 'echo'
AS $$
def echo():
return 'hi'
$$;
Cet exemple montre comment utiliser plusieurs spécificateurs de versions de paquets :
CREATE OR REPLACE FUNCTION my_udf()
RETURNS STRING
LANGUAGE PYTHON
PACKAGES = ('numpy>=1.2,<2')
RUNTIME_VERSION = 3.10
HANDLER = 'echo'
AS $$
def echo():
return 'hi'
$$;
Lecture dâun fichier¶
Vous pouvez lire le contenu dâun fichier avec le code du gestionnaire dâUDF Python. Par exemple, vous pourriez vouloir lire un fichier pour traiter des donnĂ©es non structurĂ©es.
Pour lire le contenu dâun fichier, vous pouvez :
SpĂ©cifier statistiquement le chemin et le nom du fichier avec la clause IMPORTS, puis les lire depuis le rĂ©pertoire personnel de lâUDF. Cela peut ĂȘtre utile lorsquâun nom de fichier est statique, cohĂ©rent au sein de la fonction et que vous connaissez le nom du fichier Ă lâavance.
SpĂ©cifier dynamiquement le fichier et lire son contenu avec SnowflakeFile. Vous pouvez le faire si vous avez besoin dâaccĂ©der Ă un fichier pendant un calcul.
Lecture dâun fichier spĂ©cifiĂ© de façon statique Ă lâaide de IMPORTS¶
Vous pouvez lire un fichier en spécifiant le nom du fichier et le nom de la zone de préparation dans la clause IMPORTS de la commande CREATE FUNCTION.
Lorsque vous spĂ©cifiez un fichier dans la clause IMPORTS, Snowflake copie ce fichier de la zone de prĂ©paration vers le rĂ©pertoire personnel (Ă©galement appelĂ© rĂ©pertoire dâimportation) de lâUDF, qui est le rĂ©pertoire Ă partir duquel lâUDF lit le fichier.
Snowflake copie les fichiers importĂ©s dans un rĂ©pertoire unique. Tous les fichiers de ce rĂ©pertoire doivent avoir des noms uniques, de sorte que chaque fichier de votre clause IMPORTS doit avoir un nom distinct. Cette rĂšgle sâapplique mĂȘme si les fichiers commencent dans diffĂ©rentes zones de prĂ©paration ou diffĂ©rents sous-rĂ©pertoires au sein dâune zone de prĂ©paration.
Note
Vous ne pouvez importer des fichiers quâĂ partir du rĂ©pertoire de premier niveau dâune zone de prĂ©paration, pas des sous-dossiers.
Lâexemple suivant utilise un gestionnaire Python en ligne qui lit un fichier appelĂ© file.txt
Ă partir dâune zone de prĂ©paration nommĂ©e my_stage
. Le gestionnaire rĂ©cupĂšre lâemplacement du rĂ©pertoire personnel de lâUDF en utilisant la mĂ©thode Python sys._xoptions
avec lâoption systĂšme snowflake_import_directory
.
Snowflake lit le fichier une seule fois pendant la crĂ©ation de lâUDF, et ne le relira pas pendant lâexĂ©cution de lâUDF si la lecture du fichier a lieu en dehors du gestionnaire cible.
CrĂ©ez lâUDF avec un gestionnaire en ligne :
CREATE OR REPLACE FUNCTION my_udf()
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.9
IMPORTS = ('@my_stage/file.txt')
HANDLER = 'compute'
AS $$
import sys
import os
with open(os.path.join(sys._xoptions["snowflake_import_directory"], 'file.txt'), "r") as f:
s = f.read()
def compute():
return s
$$;
Lecture dâun fichier spĂ©cifiĂ© de façon dynamique avec SnowflakeFile
¶
Vous pouvez lire un fichier depuis une zone de préparation en utilisant la classe SnowflakeFile
dans le module Snowpark snowflake.snowpark.files
. La classe SnowflakeFile
offre un accĂšs dynamique aux fichiers, ce qui vous permet de diffuser des fichiers de nâimporte quelle taille. LâaccĂšs dynamique aux fichiers est Ă©galement utile lorsque vous souhaitez itĂ©rer sur plusieurs fichiers. Par exemple, voir Traitement de plusieurs fichiers.
La classe SnowflakeFile
possÚde une méthode pour ouvrir un fichier : open
. La méthode open
renvoie un objet SnowflakeFile
qui étend les objets de fichier IOBase
Python.
Lâobjet SnowflakeFile
prend en charge les méthodes suivantes : IOBase
, BufferedIOBase
; et RawIOBase
:
IOBase.fileno
IOBase.isatty
IOBase.readable
IOBase.readinto
IOBase.readline
IOBase.readlines
IOBase.seek
IOBase.seekable
IOBase.tell
BufferedIOBase.readinto1
RawIOBase.read
RawIOBase.readall
Pour plus dâinformations, voir la documentation Python 3.9 sur IOBase. Lâappel Ă des mĂ©thodes non prises en charge dans un serveur Snowflake, telles que la mĂ©thode fileno
, entraĂźnera une erreur.
Note
Par dĂ©faut, lâaccĂšs aux fichiers avec SnowflakeFile
nĂ©cessite des URLs scopĂ©es afin de rendre votre code rĂ©sistant aux attaques par injection de fichiers. Vous pouvez crĂ©er une URL scopĂ©e en SQL Ă lâaide de la fonction intĂ©grĂ©e BUILD_SCOPED_FILE_URL. Pour plus dâinformations sur les URLs scopĂ©es, voir Types dâURLs disponibles pour accĂ©der aux fichiers. Seuls les utilisateurs ayant accĂšs au fichier peuvent crĂ©er une URL scopĂ©e.
Conditions préalables¶
Avant que votre code de gestionnaire Python puisse lire un fichier sur une zone de préparation, vous devez effectuer les opérations suivantes pour mettre le fichier à la disposition du code :
Créez une zone de préparation accessible à votre gestionnaire.
Vous pouvez utiliser une zone de prĂ©paration externe ou une zone de prĂ©paration interne. Si vous utilisez une zone de prĂ©paration interne, il peut sâagir dâune zone de prĂ©paration utilisateur lorsque vous prĂ©voyez de crĂ©er une procĂ©dure stockĂ©e avec droits de lâappelant. Sinon, vous devez utiliser une zone de prĂ©paration nommĂ©e. Snowflake ne prend actuellement pas en charge lâutilisation dâune zone de prĂ©paration de table pour les dĂ©pendances UDF.
Pour en savoir plus sur la crĂ©ation dâune zone de prĂ©paration, voir CREATE STAGE. Pour en savoir plus sur le choix dâun type de zone de prĂ©paration interne, voir SĂ©lection dâune zone de prĂ©paration interne pour les fichiers locaux.
Des privilĂšges adĂ©quats sur la zone de prĂ©paration doivent ĂȘtre attribuĂ©s au rĂŽle suivant, en fonction de votre casse :
Cas dâutilisation
RĂŽle
UDF ou procédure stockée avec droits du propriétaire
RĂŽle qui possĂšde lâUDF ou la procĂ©dure stockĂ©e en cours dâexĂ©cution.
ProcĂ©dure stockĂ©e avec droits de lâappelant
RĂŽle de lâutilisateur.
Pour plus dâinformations, voir Accorder des privilĂšges pour les fonctions dĂ©finies par lâutilisateur.
Copiez le fichier que votre code lira dans la zone de préparation.
Vous pouvez copier le fichier dâun lecteur local vers une zone de prĂ©paration interne en utilisant la commande PUT. Pour des informations sur la mise en zone de prĂ©paration de fichiers avec PUT, voir Mise en zone de prĂ©paration de fichiers de donnĂ©es Ă partir dâun systĂšme de fichiers local.
Vous pouvez copier le fichier dâun lecteur local vers une zone de prĂ©paration externe Ă lâaide de lâun des outils fournis par votre service de stockage dans le Cloud. Pour obtenir de lâaide, consultez la documentation de votre service de stockage dans le Cloud.
Calcul du hachage perceptuel dâune image avec un gestionnaire Python en ligne¶
Cet exemple utilise SnowflakeFile
pour lire une paire de fichiers images en zone de préparation et utiliser le hachage perceptuel (pHash) de chaque fichier pour déterminer le degré de similitude des images entre elles.
CrĂ©ez une UDF qui renvoie la valeur phash dâune image, en spĂ©cifiant le mode dâentrĂ©e comme Ă©tant binaire en transmettant rb
pour lâargument mode
:
CREATE OR REPLACE FUNCTION calc_phash(file_path STRING)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
PACKAGES = ('snowflake-snowpark-python','imagehash','pillow')
HANDLER = 'run'
AS $$
from PIL import Image
import imagehash
from snowflake.snowpark.files import SnowflakeFile
def run(file_path):
with SnowflakeFile.open(file_path, 'rb') as f:
return imagehash.average_hash(Image.open(f))
$$;
Créez une deuxiÚme UDF qui calcule la distance entre les valeurs de phash de deux images :
CREATE OR REPLACE FUNCTION calc_phash_distance(h1 STRING, h2 STRING)
RETURNS INT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
PACKAGES = ('imagehash')
HANDLER = 'run'
AS $$
import imagehash
def run(h1, h2):
return imagehash.hex_to_hash(h1) - imagehash.hex_to_hash(h2)
$$;
Mettez en zone de préparation les fichiers images et actualisez la table du répertoire :
PUT file:///tmp/image1.jpg @images AUTO_COMPRESS=FALSE;
PUT file:///tmp/image2.jpg @images AUTO_COMPRESS=FALSE;
ALTER STAGE images REFRESH;
Appelez lâUDFs :
SELECT
calc_phash_distance(
calc_phash(build_scoped_file_url(@images, 'image1.jpg')),
calc_phash(build_scoped_file_url(@images, 'image2.jpg'))
) ;
Traitement dâun fichier CSV Ă lâaide dâune UDTF¶
Cet exemple utilise SnowflakeFile
pour crĂ©er une UDTF qui extrait le contenu dâun fichier CSV et renvoie les lignes dans un tableau.
CrĂ©ez lâUDTF avec un gestionnaire en ligne :
CREATE FUNCTION parse_csv(file_path STRING)
RETURNS TABLE (col1 STRING, col2 STRING, col3 STRING)
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'csvparser'
AS $$
from snowflake.snowpark.files import SnowflakeFile
class csvparser:
def process(self, stagefile):
with SnowflakeFile.open(stagefile) as f:
for line in f.readlines():
lineStr = line.strip()
row = lineStr.split(",")
try:
# Read the columns from the line.
yield (row[1], row[0], row[2], )
except:
pass
$$;
Mettez en zone de préparation le fichier CSV et actualisez la table du répertoire :
PUT file:///tmp/sample.csv @data_stage AUTO_COMPRESS=FALSE;
ALTER STAGE data_stage REFRESH;
Appelez lâUDTF en lui transmettant lâURL dâun fichier :
SELECT * FROM TABLE(PARSE_CSV(build_scoped_file_url(@data_stage, 'sample.csv')));
Traitement de plusieurs fichiers¶
Vous pouvez lire et traiter plusieurs fichiers en transmettant la colonne RELATIVE_PATH dâune table de rĂ©pertoire Ă votre gestionnaire. Pour plus dâinformations sur la colonne RELATIVE_PATH, consultez le rĂ©sultat dâune requĂȘte de table de rĂ©pertoire.
Note
En fonction de la taille de vos fichiers et de vos besoins de calcul, vous pouvez utiliser ALTER WAREHOUSE pour mettre votre entrepĂŽt Ă une Ă©chelle supĂ©rieure avant dâexĂ©cuter une instruction qui lit et traite plusieurs fichiers.
- Appelez lâUDF pour traiter plusieurs fichiers :
Lâexemple suivant appelle une UDF au sein dâune instruction CREATE TABLE pour traiter chaque fichier sur une zone de prĂ©paration, puis stocker les rĂ©sultats dans une nouvelle table.
Ă des fins de dĂ©monstration, lâexemple repose sur les hypothĂšses suivantes :
Une zone de préparation nommée
my_stage
contient plusieurs fichiers texte.Il existe une UDF nommée
get_sentiment
qui effectue une analyse des sentiments sur du texte non structurĂ©. LâUDF prend en entrĂ©e le chemin dâun fichier texte et renvoie une valeur reprĂ©sentant le sentiment.
CREATE OR REPLACE TABLE sentiment_results AS SELECT relative_path , get_sentiment(build_scoped_file_url(@my_stage, relative_path)) AS sentiment FROM directory(@my_stage);
- Appelez lâUDTF pour traiter plusieurs fichiers :
Lâexemple suivant appelle une UDTF nommĂ©e
parse_excel_udtf
. Lâexemple transmet lerelative_path
de la table du répertoire à la zone de préparation nomméemy_excel_stage
.SELECT t.* FROM directory(@my_stage) d, TABLE(parse_excel_udtf(build_scoped_file_url(@my_excel_stage, relative_path)) t;
Lecture de fichiers avec des URLs et des URIs de zones de préparation¶
LâaccĂšs Ă un fichier avec SnowflakeFile
nĂ©cessite par dĂ©faut des URLs scopĂ©es. Cela rend votre code rĂ©sistant aux attaques par injection de fichiers. Toutefois, vous pouvez faire rĂ©fĂ©rence Ă lâemplacement dâun fichier en utilisant une URI ou une URL de zone de prĂ©paration. Pour ce faire, vous devez appeler la mĂ©thode SnowflakeFile.open
avec lâargument mot-clĂ© require_scoped_url = False
.
Cette option est utile lorsque vous voulez permettre Ă un fournisseur de fournir une URI qui nâest accessible quâau propriĂ©taire de lâUDF. Par exemple, vous pouvez utiliser une URI de zone de prĂ©paration pour lâaccĂšs aux fichiers si vous possĂ©dez une UDF et que vous souhaitez lire vos fichiers de configuration ou vos modĂšles de machine learning. Nous ne recommandons pas cette option si vous travaillez avec des fichiers dont les noms sont imprĂ©visibles, tels que les fichiers créés en fonction des entrĂ©es de lâutilisateur.
Cet exemple lit un modĂšle de machine learning dans un fichier et utilise le modĂšle dans une fonction pour effectuer un traitement du langage naturel pour lâanalyse des sentiments. Lâexemple appelle open
avec require_scoped_url = False
. Dans les deux formats de localisation des fichiers (URI et URL de zone de prĂ©paration), le propriĂ©taire de lâUDF doit avoir accĂšs au fichier modĂšle.
CrĂ©ez lâUDF avec un gestionnaire en ligne :
CREATE OR REPLACE FUNCTION extract_sentiment(input_data STRING)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
PACKAGES = ('snowflake-snowpark-python','scikit-learn')
HANDLER = 'run'
AS $$
from snowflake.snowpark.files import SnowflakeFile
from sklearn.linear_model import SGDClassifier
import pickle
def run(input_data):
model_file = '@models/NLP_model.pickle'
# Specify 'mode = rb' to open the file in binary mode.
with SnowflakeFile.open(model_file, 'rb', require_scoped_url = False) as f:
model = pickle.load(f)
return model.predict([input_data])[0]
$$;
Mettez en zone de préparation le fichier modÚle et actualisez la table du répertoire :
PUT file:///tmp/NLP_model.pickle @models AUTO_COMPRESS=FALSE;
ALTER STAGE models REFRESH;
Vous pouvez Ă©galement spĂ©cifier lâUDF avec lâURL de la zone de prĂ©paration du modĂšle pour extraire le sentiment.
Par exemple, créez une UDF avec un gestionnaire en ligne qui spécifie un fichier en utilisant une URL de zone de préparation :
CREATE OR REPLACE FUNCTION extract_sentiment(input_data STRING)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
PACKAGES = ('snowflake-snowpark-python','scikit-learn')
HANDLER = 'run'
AS $$
from snowflake.snowpark.files import SnowflakeFile
from sklearn.linear_model import SGDClassifier
import pickle
def run(input_data):
model_file = 'https://my_account/api/files/my_db/my_schema/models/NLP_model.pickle'
# Specify 'rb' to open the file in binary mode.
with SnowflakeFile.open(model_file, 'rb', require_scoped_url = False) as f:
model = pickle.load(f)
return model.predict([input_data])[0]
$$;
Appelez lâUDF avec les donnĂ©es dâentrĂ©e :
SELECT extract_sentiment('I am writing to express my interest in a recent posting made.');
Ăcriture de fichiers¶
Un gestionnaire dâUDF peut Ă©crire des fichiers dans un rĂ©pertoire /tmp
créé pour la requĂȘte appelant lâUDF.
Nâoubliez pas quâun rĂ©pertoire /tmp
est rĂ©servĂ© Ă une seule requĂȘte dâappel, alors que plusieurs processus de travail Python peuvent ĂȘtre exĂ©cutĂ©s en mĂȘme temps. Pour Ă©viter les collisions, vous devez vous assurer que lâaccĂšs au rĂ©pertoire /tmp est synchronisĂ© avec les autres processus de travail Python ou que les noms des fichiers Ă©crits dans /tmp sont uniques.
Pour un exemple de code, voir DĂ©compression dâun fichier en zone de prĂ©paration dans cette rubrique.
Le code de lâexemple suivant Ă©crit lâentrĂ©e text
dans le répertoire /tmp
. Il ajoute Ă©galement lâID du processus de la fonction pour garantir lâunicitĂ© de lâemplacement du fichier.
def func(text):
# Append the function's process ID to ensure the file name's uniqueness.
file_path = '/tmp/content' + str(os.getpid())
with open(file_path, "w") as file:
file.write(text)
Pour plus dâinformations sur lâĂ©criture de fichiers, voir . Ăcriture de fichiers depuis les UDFs et les UDTFs Snowpark Python.
DĂ©compression dâun fichier en zone de prĂ©paration¶
Vous pouvez stocker un fichier .zip dans une zone de préparation, puis le décompresser dans une UDF en utilisant le module Python zipfile.
Par exemple, vous pouvez tĂ©lĂ©charger un fichier .zip dans une zone de prĂ©paration, puis rĂ©fĂ©rencer le fichier .zip Ă son emplacement de zone de prĂ©paration dans la clause IMPORTS lorsque vous crĂ©ez lâUDF. Au moment de lâexĂ©cution, Snowflake copiera le fichier en zone de prĂ©paration dans un rĂ©pertoire dâimportation Ă partir duquel votre code pourra y accĂ©der.
Pour plus dâinformations sur la lecture et lâĂ©criture de fichiers, voir Lecture dâun fichier et Ăcriture de fichiers.
Dans lâexemple suivant, le code de lâUDF utilise un modĂšle NLP pour dĂ©couvrir les entitĂ©s dans le texte. Le code renvoie un tableau de ces entitĂ©s. Pour configurer le modĂšle NLP afin de traiter le texte, le code utilise dâabord le module zipfile pour extraire le fichier du modĂšle (en_core_web_sm-2.3.1) dâun fichier .zip. Le code utilise ensuite le module spaCy pour charger le modĂšle Ă partir du fichier.
Notez que le code Ă©crit le contenu des fichiers extraits dans le rĂ©pertoire /tmp créé pour la requĂȘte qui appelle cette fonction. Le code utilise des verrous de fichier pour garantir que lâextraction est synchronisĂ©e entre les processus de travail Python ; de cette façon, le contenu nâest dĂ©compressĂ© quâune seule fois. Pour plus dâinformations sur lâĂ©criture de fichiers, voir Ăcriture de fichiers.
Pour en savoir plus sur le module zipfile, consultez la rĂ©fĂ©rence zipfile. Pour en savoir plus sur le module spaCy, consultez la documentation de lâAPI spaCy.
CrĂ©ez lâUDF avec un gestionnaire en ligne :
CREATE OR REPLACE FUNCTION py_spacy(str STRING)
RETURNS ARRAY
LANGUAGE PYTHON
RUNTIME_VERSION = 3.9
HANDLER = 'func'
PACKAGES = ('spacy')
IMPORTS = ('@spacy_stage/spacy_en_core_web_sm.zip')
AS $$
import fcntl
import os
import spacy
import sys
import threading
import zipfile
# File lock class for synchronizing write access to /tmp.
class FileLock:
def __enter__(self):
self._lock = threading.Lock()
self._lock.acquire()
self._fd = open('/tmp/lockfile.LOCK', 'w+')
fcntl.lockf(self._fd, fcntl.LOCK_EX)
def __exit__(self, type, value, traceback):
self._fd.close()
self._lock.release()
# Get the location of the import directory. Snowflake sets the import
# directory location so code can retrieve the location via sys._xoptions.
IMPORT_DIRECTORY_NAME = "snowflake_import_directory"
import_dir = sys._xoptions[IMPORT_DIRECTORY_NAME]
# Get the path to the ZIP file and set the location to extract to.
zip_file_path = import_dir + "spacy_en_core_web_sm.zip"
extracted = '/tmp/en_core_web_sm'
# Extract the contents of the ZIP. This is done under the file lock
# to ensure that only one worker process unzips the contents.
with FileLock():
if not os.path.isdir(extracted + '/en_core_web_sm/en_core_web_sm-2.3.1'):
with zipfile.ZipFile(zip_file_path, 'r') as myzip:
myzip.extractall(extracted)
# Load the model from the extracted file.
nlp = spacy.load(extracted + "/en_core_web_sm/en_core_web_sm-2.3.1")
def func(text):
doc = nlp(text)
result = []
for ent in doc.ents:
result.append((ent.text, ent.start_char, ent.end_char, ent.label_))
return result
$$;
Traitement des valeurs NULL¶
Le code suivant montre comment les valeurs NULL sont traitĂ©es. Pour plus dâinformations, voir Valeurs NULL.
CrĂ©ez lâUDF :
CREATE OR REPLACE FUNCTION py_udf_null(a VARIANT)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.9
HANDLER = 'udf'
AS $$
def udf(a):
if not a:
return 'JSON null'
elif getattr(a, "is_sql_null", False):
return 'SQL null'
else:
return 'not null'
$$;
Appelez lâUDF :
SELECT py_udf_null(null);
+-------------------+
| PY_UDF_NULL(NULL) |
|-------------------|
| SQL null |
+-------------------+
SELECT py_udf_null(parse_json('null'));
+---------------------------------+
| PY_UDF_NULL(PARSE_JSON('NULL')) |
|---------------------------------|
| JSON null |
+---------------------------------+
SELECT py_udf_null(10);
+-----------------+
| PY_UDF_NULL(10) |
|-----------------|
| not null |
+-----------------+