

 Amazon Redshift non supporterà più la creazione di nuovi Python UDFs a partire dalla Patch 198. Python esistente UDFs continuerà a funzionare fino al 30 giugno 2026. Per ulteriori informazioni, consulta il [post del blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

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

Una funzione definita dall'utente Python integra un programma Python che viene eseguito quando la funzione viene chiamata e restituisce un singolo valore. Il comando [CREATE FUNCTION](r_CREATE_FUNCTION.md) definisce i parametri seguenti:
+ Argomenti di input (facoltativi). Ogni argomento deve avere un nome e un tipo di dati. 
+ Un tipo di dati restituito.
+ Un programma Python eseguibile.

I tipi di dati di input e di ritorno per Python UDFs possono essere uno dei seguenti tipi:
+  SMALLINT 
+  INTEGER 
+  BIGINT 
+  DECIMAL 
+  REAL 
+  DOUBLE PRECISION 
+  BOOLEAN 
+  CHAR 
+  VARCHAR 
+  DATE 
+  TIMESTAMP 
+  ANYELEMENT 

Anche gli alias per questi tipi sono validi. Per un elenco completo dei tipi di dati e dei relativi alias, consulta [Tipi di dati](c_Supported_data_types.md).

Quando Python UDFs utilizza il tipo di dati ANYELEMENT, Amazon Redshift converte automaticamente in un tipo di dati standard in base agli argomenti forniti in fase di esecuzione. Per ulteriori informazioni, consulta [Tipo di dati ANYELEMENT](udf-data-types.md#udf-anyelement-data-type).

Quando una query di Amazon Redshift chiama una funzione definita dall'utente scalare, si verifica quanto segue in fase di runtime.

1. La funzione converte gli argomenti di input in tipi di dati Python.

   Per una mappatura dei tipi di dati di Amazon Redshift a tipi di dati Python, consultare [Tipi di dati delle funzioni definite dall'utente Python](udf-data-types.md).

1. La funzione esegue il programma Python, passando gli argomenti di input convertiti.

1. Il codice Python restituisce un singolo valore. Il tipo di dati del valore restituito deve corrispondere al tipo di dati RETURNS specificato dalla definizione della funzione.

1. La funzione converte il valore restituito da Python nel tipo di dati di Amazon Redshift specificato e quindi restituisce il valore alla query.

**Nota**  
Python 3 non è disponibile per Python. UDFs Per ottenere il supporto di Python 3 per Amazon UDFs Redshift, usa invece. [Lambda scalare UDFs](udf-creating-a-lambda-sql-udf.md)

# Esempio di funzione definita dall'utente Python scalare
<a name="udf-scalar-function-example"></a>

L'esempio seguente crea una funzione che confronta due numeri e restituisce il valore più grande. Tenere presente che il rientro del codice tra i segni di doppio dollaro (\$1\$1) è un requisito di Python. Per ulteriori informazioni, consultare [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 query seguente chiama la nuova funzione `f_greater` per eseguire una query sulla tabella SALES e restituire il valore di COMMISSION o il 20% di PRICEPAID, a seconda di quale valore è più grande.

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

# Tipi di dati delle funzioni definite dall'utente Python
<a name="udf-data-types"></a>

Python UDFs può utilizzare qualsiasi tipo di dati Amazon Redshift standard per gli argomenti di input e il valore restituito dalla funzione. Oltre ai tipi di dati standard, UDFs supporta il tipo di dati *ANYELEMENT*, che Amazon Redshift converte automaticamente in un tipo di dati standard in base agli argomenti forniti in fase di esecuzione. Scalar UDFs può restituire un tipo di dati ANYELEMENT. Per ulteriori informazioni, consulta [Tipo di dati ANYELEMENT](#udf-anyelement-data-type).

Durante l'esecuzione, Amazon Redshift converte gli argomenti da tipi di dati Amazon Redshift a tipi di dati Python per l'elaborazione. Quindi converte il valore restituito dal tipo di dati Python al tipo di dati Amazon Redshift corrispondente. Per ulteriori informazioni sui tipi di dati di Amazon Redshift, consultare [Tipi di dati](c_Supported_data_types.md).

La tabella seguente indica la mappatura dei tipi di dati Amazon Redshift ai tipi di dati Python.

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

## Tipo di dati ANYELEMENT
<a name="udf-anyelement-data-type"></a>

ANYELEMENT è un *tipo di dati polimorfico*. Ciò significa che se una funzione viene dichiarata usando ANYELEMENT come tipo di dati di un argomento, la funzione può accettare qualsiasi tipo di dati Amazon Redshift standard come input per l'argomento quando viene chiamata. L'argomento ANYELEMENT viene impostato sul tipo di dati effettivamente passato all'argomento quando viene chiamata la funzione.

Se una funzione usa più tipi di dati ANYELEMENT, questi devono tutti essere risolti nello stesso tipo di dati effettivo quando viene chiamata la funzione. Tutti i tipi di dati dell'argomento ANYELEMENT sono impostati sull'effettivo tipo di dati del primo argomento passato a ANYELEMENT. Ad esempio, una funzione dichiarata come `f_equal(anyelement, anyelement)` accetta uno qualsiasi tra due valori di input, purché abbiano lo stesso tipo di dati.

Se il valore restituito di una funzione viene dichiarato come ANYELEMENT, almeno un argomento di input deve essere ANYELEMENT. Il tipo di dati effettivo per il valore restituito sarà lo stesso del tipo di dati effettivo specificato per l'argomento di input ANYELEMENT. 

# Supporto del linguaggio Python per UDFs
<a name="udf-python-language-support"></a>

Puoi creare una funzione definita dall'utente personalizzata basata sul linguaggio di programmazione Python. La [libreria standard Python 2.7](https://docs.python.org/2/library/index.html) è disponibile per l'uso in UDFs, ad eccezione dei seguenti moduli:
+ ScrolledText
+ Tix
+ Tkinter
+ tk
+ turtle
+ smtpd

Oltre alla libreria standard Python, i moduli seguenti fanno parte dell'implementazione di 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)

Puoi anche importare i tuoi moduli Python personalizzati e renderli disponibili per l'uso UDFs eseguendo un [CREATE LIBRARY](r_CREATE_LIBRARY.md) comando. Per ulteriori informazioni, consulta [Esempio: importazione di moduli di libreria Python personalizzati](udf-importing-custom-python-library-modules.md).

**Importante**  
Amazon Redshift blocca tutti gli accessi alla rete e gli accessi in scrittura al file system tramite. UDFs

**Nota**  
Python 3 non è disponibile per Python. UDFs Per ottenere il supporto di Python 3 per Amazon UDFs Redshift, usa invece. [Lambda scalare UDFs](udf-creating-a-lambda-sql-udf.md)

# Esempio: importazione di moduli di libreria Python personalizzati
<a name="udf-importing-custom-python-library-modules"></a>

Puoi definire funzioni scalari usando la sintassi del linguaggio Python. È possibile utilizzare i moduli di libreria Python standard e i moduli Amazon Redshift preinstallati. Inoltre è possibile creare moduli di libreria Python personalizzati e importare le librerie nei cluster oppure usare librerie esistenti da Python o da terze parti. 

Non è possibile creare una libreria che contiene un modulo con lo stesso nome di un modulo della libreria standard Python o un modulo Python preinstallato in Amazon Redshift. Se una libreria installata dall'utente esistente usa lo stesso pacchetto Python di una libreria creata da te, devi eliminare la libreria esistente prima di installare quella nuova. 

Per installare librerie personalizzate, devi essere un utente con privilegi avanzati o avere il privilegio `USAGE ON LANGUAGE plpythonu`. Tuttavia, qualsiasi utente con privilegi sufficienti per la creazione di funzioni può usare le librerie installate. Puoi eseguire query sul catalogo di sistema [PG\$1LIBRARY](r_PG_LIBRARY.md) per visualizzare informazioni sulle librerie installate nel cluster.

## Importazione di un modulo Python personalizzato nel cluster
<a name="udf-import-custom-python-module-procedure"></a>

Questa sezione presenta un esempio di importazione di un modulo Python personalizzato nel cluster. Per completare la procedura in questa sezione, è necessario disporre di un bucket Amazon S3 in cui caricare il pacchetto della libreria. Devi quindi installare il pacchetto nel cluster. Per ulteriori informazioni sulla creazione di un bucket, consultare [Creazione di un bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingaBucket.html) nella *Guida per l'utente di Amazon Simple Storage Service*.

In questo esempio, supponiamo che tu crei UDFs per lavorare con posizioni e distanze nei tuoi dati. Connettersi al cluster Amazon Redshift da uno strumento client SQL ed eseguire i comandi seguenti per creare le funzioni. 

```
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;
```

Come puoi notare, nell'esempio precedente alcune righe di codice sono duplicate. Queste righe duplicate sono necessarie, perché una funzione definita dell'utente non può fare riferimento al contenuto di un'altra funzione definita dall'utente ed entrambe le funzioni devono avere le stesse funzionalità. Tuttavia, invece di duplicare il codice in più funzioni, puoi creare una libreria personalizzata e configurare le funzioni perché la usino. 

A questo scopo, crea prima di tutto il pacchetto della libreria completando questa procedura: 

1. Creare una cartella denominata **geometry**. Questa cartella è il pacchetto di primo livello della libreria.

1. Nella cartella **geometry** creare un file denominato `__init__.py`. Notare che il nome del file contiene due caratteri di sottolineatura doppi. Questo file indica a Python che il pacchetto può essere inizializzato.

1. Nella cartella **geometry** creare una cartella denominata **trig**. Questa cartella è il sottopacchetto della libreria.

1. Nella cartella **trig** creare un altro file denominato `__init__.py` e un file denominato `line.py`. In questa cartella `__init__.py` indica a Python che il sottopacchetto può essere inizializzato e che `line.py` è il file che contiene il codice della libreria.

   La struttura dei file e delle cartelle deve essere uguale alla seguente: 

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

    Per ulteriori informazioni sulla struttura dei pacchetti, consultare la pagina relativa ai [moduli](https://docs.python.org/2/tutorial/modules.html) nel tutorial su Python nel sito Web Python. 

1.  Il codice seguente contiene una classe e funzioni membro per la libreria. Copiare e incollare il codice in `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)
   ```

 Dopo aver creato il pacchetto, completare le operazioni seguenti per prepararlo e caricarlo in Amazon S3. 

1. Comprimere il contenuto della cartella **geometry** in un file ZIP denominato **geometry.zip**. Non includere la cartella **geometry** stessa, ma solo il contenuto della cartella, come mostrato di seguito: 

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

1. Caricare **geometry.zip** sul bucket Amazon S3.
**Importante**  
 Se il bucket Amazon S3 non si trova nella stessa regione del cluster Amazon Redshift, è necessario utilizzare l'opzione REGION per specificare la regione in cui si trovano i dati. Per ulteriori informazioni, consultare [CREATE LIBRARY](r_CREATE_LIBRARY.md).

1.  Dallo strumento client SQL eseguire il comando seguente per installare la libreria. Sostituiscilo *<bucket\$1name>* con il nome del bucket e sostituiscilo *<secret key>* con una chiave di accesso *<access key id>* e una chiave di accesso segreta ricavate dalle tue credenziali utente AWS Identity and Access Management (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>';
   ```

 Dopo aver installato la libreria nel cluster, devi configurare le funzioni per l'uso della libreria. A questo scopo, esegui i comandi seguenti. 

```
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;
```

Nei comandi precedenti `import trig/line` elimina il codice duplicato dalle funzioni originali in questa sezione. È possibile riutilizzare le funzionalità fornite da questa libreria in più modi. UDFs Tieni presente che per importare il modulo, devi solo specificare il percorso del sottopacchetto e il nome del modulo (`trig/line`). 

# Vincoli delle UDF Python
<a name="udf-constraints"></a>

Entro i limiti elencati in questo argomento, puoi utilizzare UDFs ovunque utilizzi le funzioni scalari integrate di Amazon Redshift. Per ulteriori informazioni, consulta [Informazioni di riferimento sulle funzioni SQL](c_SQL_functions.md).

Amazon Redshift Python UDFs presenta i seguenti vincoli:
+ Python UDFs non può accedere alla rete o leggere o scrivere nel file system.
+ Le dimensioni totali delle librerie Python installate dall'utente non possono superare 100 MB.
+ Amazon Redshift può eseguire solo una UDF Python alla volta per cluster con provisioning che utilizzano la gestione dei carichi di lavoro (WLM) automatica e per gruppi di lavoro serverless. Se tenti di eseguire più di un UDF contemporaneamente, Amazon Redshift mette in coda il UDFs Python rimanente da eseguire nelle code di gestione del carico di lavoro. SQL UDFs non ha un limite di concorrenza quando utilizza il WLM automatico. 
+  Quando si utilizza WLM manuale per i cluster con provisioning, il numero di Python UDFs che possono essere eseguiti contemporaneamente per cluster è limitato a un quarto del livello di concorrenza totale del cluster. Ad esempio, un cluster fornito con una concorrenza di 15 può eseguire un massimo di tre Python simultanei. UDFs 
+ Quando si utilizza Python UDFs, Amazon Redshift non supporta i tipi di dati SUPER e HLLSKETCH.

# Registrazione di errori e avvisi in Python UDFs
<a name="udf-logging-messages"></a>

Puoi usare il modulo di registrazione Python per creare messaggi di errore e avviso definiti dall'utente nel tuo. UDFs In seguito all'esecuzione della query, puoi eseguire una query sulla vista di sistema [SVL\$1UDF\$1LOG](r_SVL_UDF_LOG.md) per recuperare i messaggi registrati.

**Nota**  
Il logging di funzioni definite dall'utente utilizza risorse del cluster e può influire sulle prestazioni del sistema. Ti consigliamo di implementare il logging solo per scopi di sviluppo e risoluzione dei problemi. 

Durante l'esecuzione delle query, il gestore dei log scrive messaggi nella vista di sistema SVL\$1UDF\$1LOG, insieme a nome, nodo e sezione della funzione corrispondente. Il gestore dei log scrive una riga nella vista di sistema SVL\$1UDF\$1LOG per ogni messaggio e per ogni sezione. I messaggi vengono troncati a 4096 byte. I log delle funzioni definite dall'utente è limitato a 500 righe per sezione. Quando il log è pieno, il gestore dei log elimina i messaggi meno recenti e aggiunge un messaggio di avviso in SVL\$1UDF\$1LOG.

**Nota**  
Il gestore dei log delle funzioni definite dall'utente di Amazon Redshift aggiunge a caratteri di nuova riga (`\n`), caratteri di barra verticale (`|`) e caratteri di barra rovesciata (`\`) un carattere di barra rovesciata (`\`) per l'escape.

Per impostazione predefinita, il livello di log delle funzioni definite dall'utente è impostato su WARNING. I messaggi con livello di log WARNING, ERROR e CRITICAL vengono registrati. I messaggi con gravità minore, come INFO, DEBUG e NOTSET, vengono ignorati. Per impostare il livello di log delle funzioni definite dall'utente, usa il metodo logger Python. Ad esempio, il codice seguente imposta il livello di log su INFO.

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

Per ulteriori informazioni sull'uso del modulo di logging Python, consultare la pagina relativa all'[utilità di logging per Python](https://docs.python.org/2.7/library/logging.html) nella documentazione di Python.

L'esempio seguente crea una funzione denominata f\$1pyerror che importa il modulo di logging Python, crea un'istanza del logger e registra un errore.

```
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'esempio seguente esegue una query su SVL\$1UDF\$1LOG per visualizzare il messaggio registrato nell'esempio precedente.

```
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
```