

 Amazon Redshift ne prendra plus en charge la création de nouveaux Python à UDFs partir du patch 198. UDFs Le Python existant continuera de fonctionner jusqu'au 30 juin 2026. Pour plus d’informations, consultez le [ billet de blog ](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Python scalaire UDFs
<a name="udf-creating-a-scalar-udf"></a>

Une fonction scalaire Python définie par l'utilisateur intègre un programme Python qui s'exécute lorsque la fonction est appelée et renvoie une valeur unique. La commande [CREATE FUNCTION](r_CREATE_FUNCTION.md) définit les paramètres suivants :
+ (Facultatif) Arguments d’entrée. Chaque argument doit disposer d'un nom et d'un type de données. 
+ Un type de données de retour.
+ Un programme Python exécutable.

Les types de données d'entrée et de retour pour Python UDFs peuvent être l'un des types suivants :
+  SMALLINT 
+  INTEGER 
+  BIGINT 
+  DECIMAL 
+  REAL 
+  DOUBLE PRECISION 
+  BOOLEAN 
+  CHAR 
+  VARCHAR 
+  DATE 
+  TIMESTAMP 
+  ANYELEMENT 

Les alias de ces types sont également valides. Pour obtenir la liste complète des types de données et de leurs alias, consultez [Types de données](c_Supported_data_types.md).

Lorsque Python UDFs utilise le type de données ANYELEMENT, Amazon Redshift le convertit automatiquement en un type de données standard en fonction des arguments fournis lors de l'exécution. Pour de plus amples informations, veuillez consulter [Type de données ANYELEMENT](udf-data-types.md#udf-anyelement-data-type).

Lorsqu'une requête Amazon Redshift appelle une fonction UDF scalaire, les étapes suivantes se produisent au moment de l'exécution :

1. La fonction convertit les arguments d'entrée en types de données Python.

   Pour un mappage des types de données Amazon Redshift avec les types de données Python, consultez [Types de données de fonctions Python définies par l’utilisateur](udf-data-types.md).

1. La fonction exécute le programme Python, en transmettant les arguments d'entrée convertis.

1. Le code Python renvoie une valeur unique. Le type de données de la valeur de retour doit correspondre au type de données RETURNS spécifié par la définition de fonction.

1. La fonction convertit la valeur de retour Python dans le type de données Amazon Redshift, puis renvoie cette valeur à la requête.

**Note**  
Python 3 n'est pas disponible pour Python UDFs. Pour bénéficier de la prise en charge de Python 3 pour Amazon Redshift UDFs, utilisez [Lambda scalaire UDFs](udf-creating-a-lambda-sql-udf.md) plutôt.

# Exemple de fonction scalaire Python définie par l’utilisateur
<a name="udf-scalar-function-example"></a>

L’exemple suivant crée une fonction qui compare deux nombres et renvoie la valeur la plus grande. Notez que la mise en retrait du code entre les signes de dollar doubles (\$1\$1) est une exigence Python. Pour plus d'informations, consultez [CREATE FUNCTION](r_CREATE_FUNCTION.md).

```
create function f_py_greater (a float, b float)
  returns float
stable
as $$
  if a > b:
    return a
  return b
$$ language plpythonu;
```

La requête suivante appelle la nouvelle fonction `f_greater` pour interroger la table SALES et renvoyer COMMISSION ou 20 % du PRICEPAID, quelle que soit la valeur la plus grande.

```
select f_py_greater (commission, pricepaid*0.20) from sales;
```

# Types de données de fonctions Python définies par l’utilisateur
<a name="udf-data-types"></a>

Python UDFs peut utiliser n'importe quel type de données Amazon Redshift standard pour les arguments d'entrée et la valeur de retour de la fonction. Outre les types de données standard, prenez en UDFs charge le type de données *ANYELEMENT*, qu'Amazon Redshift convertit automatiquement en type de données standard en fonction des arguments fournis lors de l'exécution. Scalar UDFs peut renvoyer un type de données ANYELEMENT. Pour de plus amples informations, veuillez consulter [Type de données ANYELEMENT](#udf-anyelement-data-type).

Au cours de l'exécution, Amazon Redshift convertit les arguments des types de données Amazon Redshift en types de données Python pour pouvoir les traiter. Il convertit ensuite la valeur de retour du type de données Python en type de données Amazon Redshift correspondant. Pour plus d'informations sur les types de données Amazon Redshift, consultez [Types de données](c_Supported_data_types.md).

Le tableau suivant mappe les types de données Amazon Redshift aux types de données Python.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/redshift/latest/dg/udf-data-types.html)

## Type de données ANYELEMENT
<a name="udf-anyelement-data-type"></a>

ANYELEMENT est un *type de données polymorphe*. Cela signifie que si une fonction est déclarée à l'aide de ANYELEMENT pour un type de données d'argument, la fonction peut accepter tous les types de données Amazon Redshift standard comme entrée pour cet argument lorsque la fonction est appelée. L'argument ANYELEMENT est défini sur le type de données qui lui est réellement transmis lorsque la fonction est appelée.

Si une fonction utilise plusieurs types de données ANYELEMENT, ils doivent tous être résolus au même type de données réel lorsque la fonction est appelée. Tous les types de données d'argument ANYELEMENT sont définies sur le type de données réel du premier argument transmis à un ANYELEMENT. Par exemple, une fonction déclarée comme `f_equal(anyelement, anyelement)` prendra les deux valeurs d'entrée, tant qu'elles sont du même type de données.

Si la valeur de retour d'une fonction est déclarée comme ANYELEMENT, au moins un argument d'entrée doit être ANYELEMENT. Le type de données réel de la valeur de retour est identique au type de données réel fourni pour l'argument d'entrée ANYELEMENT. 

# Support du langage Python pour UDFs
<a name="udf-python-language-support"></a>

Vous pouvez créer une fonction UDF personnalisée basée sur le langage de programmation Python. La [bibliothèque standard Python 2.7](https://docs.python.org/2/library/index.html) peut être utilisée dans UDFs, à l'exception des modules suivants :
+ ScrolledText
+ Tix
+ Tkinter
+ tk
+ turtle
+ smtpd

En plus de la bibliothèque standard Python, les modules suivants font partie de la mise en œuvre d'Amazon Redshift :
+ [numpy 1.8.2](http://www.numpy.org/)
+ [pandas 0.14.1](https://pandas.pydata.org/)
+ [python-dateutil 2.2](https://dateutil.readthedocs.org/en/latest/)
+ [pytz 2014.7](https://pypi.org/project/pytz/2014.7/)
+ [scipy 0.12.1](https://www.scipy.org/)
+ [six 1.3.0](https://pypi.org/project/six/1.3.0/)
+ [wsgiref 0.1.2](https://pypi.python.org/pypi/wsgiref)

Vous pouvez également importer vos propres modules Python personnalisés et les rendre utilisables en UDFs exécutant une [CREATE LIBRARY](r_CREATE_LIBRARY.md) commande. Pour de plus amples informations, veuillez consulter [Exemple : importation des modules de la bibliothèque Python personnalisés](udf-importing-custom-python-library-modules.md).

**Important**  
Amazon Redshift bloque tout accès réseau et tout accès en écriture au système de fichiers par le biais du système de fichiers. UDFs

**Note**  
Python 3 n'est pas disponible pour Python UDFs. Pour bénéficier de la prise en charge de Python 3 pour Amazon Redshift UDFs, utilisez [Lambda scalaire UDFs](udf-creating-a-lambda-sql-udf.md) plutôt.

# Exemple : importation des modules de la bibliothèque Python personnalisés
<a name="udf-importing-custom-python-library-modules"></a>

Vous définissez les fonctions scalaires à l'aide de la syntaxe du langage Python. Vous pouvez utiliser les modules de la bibliothèque standard Python et les modules préinstallés d'Amazon Redshift. Vous pouvez également créer vos propres modules de bibliothèque Python personnalisés et importer les bibliothèques dans vos clusters, ou utiliser des bibliothèques existantes de Python ou de tiers. 

Vous ne pouvez pas créer une bibliothèque qui contient un module avec le même nom qu'un module de la bibliothèque standard Python ou qu'un module Amazon Redshift préinstallé. Si une bibliothèque existante installée par l'utilisateur emploie le même package Python qu'une bibliothèque que vous créez, vous devez supprimer la bibliothèque existante avant d'installer la nouvelle bibliothèque. 

Vous devez être un super-utilisateur ou disposer du privilège `USAGE ON LANGUAGE plpythonu` pour installer des bibliothèques personnalisées. Toutefois, tous les utilisateurs disposant de privilèges suffisants pour créer des fonctions peuvent utiliser les bibliothèques installées. Vous pouvez interroger le catalogue système [PG\$1LIBRARY](r_PG_LIBRARY.md) pour afficher des informations sur les bibliothèques installées sur votre cluster.

## Importation d’un module Python personnalisé dans votre cluster
<a name="udf-import-custom-python-module-procedure"></a>

Cette section fournit un exemple d'importation d'un module Python personnalisé dans votre cluster. Pour effectuer les étapes de cette section, vous devez disposer d'un compartiment Amazon S3, dans lequel vous téléchargez le package de la bibliothèque. Ensuite, vous installez le package dans votre cluster. Pour plus d'informations sur la création de compartiments, consultez [Création d'un compartiment](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingaBucket.html) dans le *Guide de l'utilisateur Amazon Simple Storage Service*.

Dans cet exemple, supposons que vous créez UDFs pour travailler avec des positions et des distances dans vos données. Connectez-vous à votre cluster Amazon Redshift depuis un outil client SQL et exécutez les commandes suivantes pour créer les fonctions. 

```
CREATE FUNCTION f_distance (x1 float, y1 float, x2 float, y2 float) RETURNS float IMMUTABLE as $$
    def distance(x1, y1, x2, y2):
        import math
        return math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2)
 
    return distance(x1, y1, x2, y2)
$$ LANGUAGE plpythonu;
 
CREATE FUNCTION f_within_range (x1 float, y1 float, x2 float, y2 float) RETURNS bool IMMUTABLE as $$ 
    def distance(x1, y1, x2, y2):
        import math
        return math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2)
 
    return distance(x1, y1, x2, y2) < 20
$$ LANGUAGE plpythonu;
```

Notez que quelques lignes de code sont identiques dans les fonctions précédentes. Cette duplication est nécessaire, car une fonction UDF ne peut pas faire référence au contenu d'une autre fonction UDF et que les deux fonctions nécessitent la même fonctionnalité. Cependant, au lieu de dupliquer le code dans plusieurs fonctions, vous pouvez créer une bibliothèque personnalisée et configurer vos fonctions pour l'utiliser. 

Pour ce faire, commencez par créer le package de la bibliothèque en procédant comme suit : 

1. Créez un dossier nommé **geometry**. Ce dossier constitue le package de niveau supérieur de la bibliothèque.

1. Dans le **geometry**, créez un fichier nommé `__init__.py`. Notez que le nom du fichier contient deux caractères de soulignement doubles. Ce fichier indique à Python que le package peut être initialisé.

1. Toujours dans le dossier **geometry**, créez un dossier nommé **trig**. Ce dossier constitue le sous-package de la bibliothèque.

1. Dans le dossier **trig**, créez un autre fichier nommé `__init__.py` et un fichier nommé `line.py`. Dans ce dossier, `__init__.py` indique à Python que le sous-package peut être initialisé et que `line.py` est le fichier qui contient le code de la bibliothèque.

   Votre structure de dossier et de fichier devrait être la même que la suivante : 

   ```
   geometry/
      __init__.py
      trig/
         __init__.py
         line.py
   ```

    Pour plus d'informations sur la structure du package, consultez la section [ Modules](https://docs.python.org/2/tutorial/modules.html) du didacticiel Python sur le site web de Python. 

1.  Le code suivant contient une classe et des fonctions de membre pour la bibliothèque. Copiez et collez-le dans `line.py`. 

   ```
   class LineSegment:
     def __init__(self, x1, y1, x2, y2):
       self.x1 = x1
       self.y1 = y1
       self.x2 = x2
       self.y2 = y2
     def angle(self):
       import math
       return math.atan2(self.y2 - self.y1, self.x2 - self.x1)
     def distance(self):
       import math
       return math.sqrt((self.y2 - self.y1) ** 2 + (self.x2 - self.x1) ** 2)
   ```

 Une fois que vous avez créé le package, procédez comme suit pour préparer le package et chargez-le dans Amazon S3. 

1. Compressez le contenu du dossier **geometry** dans un fichier .zip nommé **geometry.zip**. N'incluez pas le dossier **geometry** lui-même ; incluez uniquement le contenu du dossier comme illustré ci-après : 

   ```
   geometry.zip
      __init__.py
      trig/
         __init__.py
         line.py
   ```

1. Téléchargez **geometry.zip** dans votre compartiment Amazon S3.
**Important**  
 Si le compartiment Amazon S3 ne réside pas dans la même région que votre cluster Amazon Redshift, vous devez utiliser l'option REGION pour spécifier la région dans laquelle les données se trouvent. Pour plus d'informations, consultez [CREATE LIBRARY](r_CREATE_LIBRARY.md).

1.  A partir de votre outil client SQL, exécutez la commande suivante pour installer la bibliothèque. *<bucket\$1name>*Remplacez-le par le nom de votre compartiment, puis par *<access key id>* une clé *<secret key>* d'accès et une clé d'accès secrète provenant de vos informations d'identification utilisateur Gestion des identités et des accès AWS (IAM). 

   ```
   CREATE LIBRARY geometry LANGUAGE plpythonu FROM 's3://<bucket_name>/geometry.zip' CREDENTIALS 'aws_access_key_id=<access key id>;aws_secret_access_key=<secret key>';
   ```

 Après avoir installé la bibliothèque dans votre cluster, vous devez configurer vos fonctions en vue d'utiliser la bibliothèque. Pour ce faire, exécutez les commandes suivantes. 

```
CREATE OR REPLACE FUNCTION f_distance (x1 float, y1 float, x2 float, y2 float) RETURNS float IMMUTABLE as $$ 
    from trig.line import LineSegment
 
    return LineSegment(x1, y1, x2, y2).distance()
$$ LANGUAGE plpythonu;
 
CREATE OR REPLACE FUNCTION f_within_range (x1 float, y1 float, x2 float, y2 float) RETURNS bool IMMUTABLE as $$ 
    from trig.line import LineSegment
 
    return LineSegment(x1, y1, x2, y2).distance() < 20
$$ LANGUAGE plpythonu;
```

Dans les commandes précédentes, `import trig/line` supprime le code dupliqué des fonctions d'origine dans cette section. Vous pouvez réutiliser les fonctionnalités fournies par cette bibliothèque à plusieurs reprises UDFs. Notez que pour importer le module, vous ne devez pas spécifier le chemin d'accès au nom du sous-package et du module (`trig/line`). 

# Contraintes des fonctions Python définies par l’utilisation
<a name="udf-constraints"></a>

Dans le cadre des contraintes répertoriées dans cette rubrique, vous pouvez les utiliser UDFs partout où vous utilisez les fonctions scalaires intégrées d'Amazon Redshift. Pour de plus amples informations, veuillez consulter [Référence sur les fonctions SQL](c_SQL_functions.md).

Amazon Redshift Python est soumis aux UDFs contraintes suivantes :
+ Python UDFs ne peut pas accéder au réseau ni lire ou écrire dans le système de fichiers.
+ La taille totale des bibliothèques Python installées par l'utilisateur ne peut pas dépasser 100 Mo.
+ Amazon Redshift ne peut exécuter qu’une seule fonction Python définie par l’utilisateur à la fois pour les clusters alloués à l’aide de la gestion automatique de la charge de travail (WLM) et pour les groupes de travail sans serveur. Si vous essayez d'exécuter plusieurs UDF simultanément, Amazon Redshift met en file d'attente le UDFs Python restant pour qu'il soit exécuté dans les files d'attente de gestion de la charge de travail. SQL UDFs n'a pas de limite de simultanéité lors de l'utilisation du WLM automatique. 
+  Lorsque vous utilisez le WLM manuel pour des clusters provisionnés, le nombre de Python UDFs pouvant être exécutés simultanément par cluster est limité à un quart du niveau de simultanéité total du cluster. Par exemple, un cluster provisionné avec une simultanéité de 15 peut exécuter un maximum de trois Python simultanés. UDFs 
+ Lorsque vous utilisez Python UDFs, Amazon Redshift ne prend pas en charge les types de données SUPER et HLLSKETCH.

# Erreurs de journalisation et avertissements en Python UDFs
<a name="udf-logging-messages"></a>

Vous pouvez utiliser le module de journalisation Python pour créer des messages d'erreur et d'avertissement définis par l'utilisateur dans votre UDFs. Après l’exécution d’une requête, vous pouvez interroger la vue système [SVL\$1UDF\$1LOG](r_SVL_UDF_LOG.md) pour récupérer les messages journalisés.

**Note**  
La journalisation UDF consomme des ressources de cluster et peut affecter les performances du système. Nous vous recommandons d'implémenter la journalisation uniquement pour le développement et le dépannage. 

Lors de l'exécution de requête, le gestionnaire de journal écrit des messages dans la vue système SVL\$1UDF\$1LOG avec le noms de fonction, le nœud et la tranche correspondants. Le gestionnaire de journal écrit une ligne dans SVL\$1UDF\$1LOG par message, par tranche. Les messages sont tronqués à 4096 octets. Le journal UDF est limité à 500 lignes par tranche. Lorsque le journal est plein, le gestionnaire de journal élimine les messages les plus anciens et ajoute un message d'avertissement dans SVL\$1UDF\$1LOG.

**Note**  
Le gestionnaire de journal UDF Amazon Redshift met en échappement les nouvelles lignes ( `\n` ), les barres verticale ( `|` ) et les barres obliques inverses ( `\` ) avec une barre oblique inverse ( `\` ).

Par défaut, la valeur de journal UDF est définie sur WARNING (Avertissement). Les messages avec le niveau de journal WARNING, ERROR et CRITICAL sont journalisés. Les messages avec une gravité plus faible INFO, DEBUG et NOTSET sont ignorés. Pour définir le niveau de journal UDF log level, utilisez la méthode logger Python. Par exemple, la commande suivante définit le niveau de journal sur INFO.

```
logger.setLevel(logging.INFO)
```

Pour plus d'informations sur l'utilisation du module de journalisation Python, consultez [Logging facility for Python](https://docs.python.org/2.7/library/logging.html) dans la documentation Python.

L'exemple suivant crée une fonction nommée f\$1pyerror qui importe le module de journalisation Python, instancie la méthode logger et journalise une erreur.

```
CREATE OR REPLACE FUNCTION f_pyerror() 
RETURNS INTEGER
VOLATILE AS
$$
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.info('Your info message here') 
return 0
$$ language plpythonu;
```

L'exemple suivant interroge SVL\$1UDF\$1LOG pour afficher le message journalisé dans l'exemple précédent.

```
select funcname, node, slice, trim(message) as message 
from svl_udf_log;

  funcname  | query | node | slice |   message  
------------+-------+------+-------+------------------
  f_pyerror | 12345 |     1|     1 | Your info message here
```