

 O Amazon Redshift não permitirá mais a criação de UDFs do Python a partir do Patch 198. As UDFs do Python existentes continuarão a funcionar normalmente até 30 de junho de 2026. Para ter mais informações, consulte a [publicação de blog ](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

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

Uma UDF Python escalar incorpora um programa Python que é executado quando a função é chamada e retorna um valor único. O comando [CREATE FUNCTION](r_CREATE_FUNCTION.md) define os seguintes parâmetros:
+ Argumentos de entrada (opcionais). Cada argumento deve ter um nome e um tipo de dados. 
+ Um tipo de dados de retorno.
+ Um programa Python executável.

Os tipos de dados de entrada e de retorno para UDFs Python podem ser qualquer um destes:
+  SMALLINT 
+  INTEGER 
+  BIGINT 
+  DECIMAL 
+  REAL 
+  DOUBLE PRECISION 
+  BOOLEAN 
+  CHAR 
+  VARCHAR 
+  DATE 
+  TIMESTAMP 
+  ANYELEMENT 

Os aliases desses tipos também são válidos. Para ver uma lista completa dos tipos de dados e os respectivos aliases, consulte [Tipos de dados](c_Supported_data_types.md).

Quando UDFs Python podem usar o tipo de dados ANYELEMENT, o Amazon Redshift converte automaticamente em um tipo de dados padrão com base nos argumentos fornecidos em tempo de execução. Para obter mais informações, consulte [Tipo de dados ANYELEMENT](udf-data-types.md#udf-anyelement-data-type).

Quando uma consulta do Amazon Redshift chama uma UDF escalar, as seguintes etapas ocorrem no tempo de execução:

1. A função converte os argumentos de entrada para tipos de dados Python.

   Para obter um mapeamento de tipos de dados Amazon Redshift para tipos de dados Python, consulte [Tipos de dados da UDF Python](udf-data-types.md).

1. A função executa o programa Python, passando os argumentos de entrada convertidos.

1. O código Python retorna um único valor. O tipo de dados do valor de retorno deve corresponder ao tipo de dados de RETURNS especificado pela definição da função.

1. A função converte o valor de retorno do Python no tipo de dados Amazon Redshift especificado e, em seguida, retorna esse valor para a consulta.

**nota**  
O Python 3 não está disponível para UDFs do Python. Para obter suporte ao Python 3 para UDFs do Amazon Redshift, use [UDFs escalares do Lambda](udf-creating-a-lambda-sql-udf.md).

# Exemplo de UDF Python escalar
<a name="udf-scalar-function-example"></a>

O seguinte exemplo cria uma função que compara dois números e retorna o maior valor. Observe que o recuo do código entre os cifrões duplos (\$1\$1) é um requisito do Python. Para obter mais informações, consulte [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;
```

A seguinte consulta chama a nova função `f_greater` para consultar a tabela SALES e retornar a COMMISSION ou 20 por cento de PRICEPAID, o que for maior.

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

# Tipos de dados da UDF Python
<a name="udf-data-types"></a>

As UDFs Python podem usar qualquer tipo de dados padrão do Amazon Redshift para os argumentos de entrada e o valor de retorno da função. Além dos tipos de dados padrão, as UDFs suportam o tipo de dados *ANYELEMENT*, que o Amazon Redshift converte automaticamente em um tipo de dados padrão com base nos argumentos fornecidos no tempo de execução. UDFs escalares podem retornar um tipo de dado ANYELEMENT. Para obter mais informações, consulte [Tipo de dados ANYELEMENT](#udf-anyelement-data-type).

Durante a execução, o Amazon Redshift converte os argumentos dos tipos de dados do Amazon Redshift para tipos de dados Python para processamento. Em seguida, ele converte o valor de retorno do tipo de dados Python para o tipo de dados do Amazon Redshift correspondente. Para obter mais informações sobre tipos de dados do Amazon Redshift, consulte [Tipos de dados](c_Supported_data_types.md).

A tabela a seguir mapeia tipos de dados Amazon Redshift para tipos de dados Python.

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

## Tipo de dados ANYELEMENT
<a name="udf-anyelement-data-type"></a>

ANYELEMENT é um *tipo de dados polimórfico*. Isso significa que se uma função for declarada usando ANYELEMENT para o tipo de dados de um argumento, a função pode aceitar qualquer tipo de dados Amazon Redshift padrão como entrada para esse argumento quando a função é chamada. O argumento de ANYELEMENT é definido para o tipo de dados realmente transmitido para ele quando a função é chamada.

Se uma função usa vários tipos de dados ANYELEMENT, todos devem se resolver para o mesmo tipo de dados real quando a função é chamada. Todos os tipos de dados de argumento ANYELEMENT são definidos como o tipo de dados real do primeiro argumento transmitido para um ANYELEMENT. Por exemplo, uma função declarada como `f_equal(anyelement, anyelement)` aceitará quaisquer dois valores de entrada, desde que eles sejam do mesmo tipo de dados.

Se o valor de retorno de uma função é declarado como ANYELEMENT, pelo menos um argumento de entrada deve ser ANYELEMENT. O tipo de dados real para o valor de retorno é o mesmo que o tipo de dados real fornecido para o argumento de entrada ANYELEMENT. 

# Suporte da linguagem Python para UDFs
<a name="udf-python-language-support"></a>

Você pode criar uma UDF personalizada com base na linguagem de programação Python. A [Biblioteca padrão Python 2.7](https://docs.python.org/2/library/index.html) está disponível para uso em UDFs, com exceção dos seguintes módulos:
+ ScrolledText
+ Tix
+ Tkinter
+ tk
+ turtle
+ smtpd

Além da biblioteca padrão do Python, os seguintes módulos fazem parte da implementação do 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)

Você também pode importar seus próprios módulos Python personalizados e disponibilizá-los para uso em UDFs executando um comando [CREATE LIBRARY](r_CREATE_LIBRARY.md). Para obter mais informações, consulte [Exemplo: importar módulos personalizados da biblioteca Python](udf-importing-custom-python-library-modules.md).

**Importante**  
O Amazon Redshift bloqueia todo o acesso à rede e acesso de gravação ao sistema de arquivos por meio de UDFs.

**nota**  
O Python 3 não está disponível para UDFs do Python. Para obter suporte ao Python 3 para UDFs do Amazon Redshift, use [UDFs escalares do Lambda](udf-creating-a-lambda-sql-udf.md).

# Exemplo: importar módulos personalizados da biblioteca Python
<a name="udf-importing-custom-python-library-modules"></a>

Você define funções escalares usando a sintaxe de linguagem Python. Você pode usar os módulos Python Standard Library e os módulos pré-instalados do Amazon Redshift. Você também pode criar seus próprios módulos personalizados da biblioteca Python e importar as bibliotecas para seus clusters ou usar bibliotecas existentes do Python ou de terceiros. 

Você não pode criar uma biblioteca que contém um módulo com o mesmo nome de um módulo de biblioteca padrão Python ou um módulo Python pré-instalado do Amazon Redshift. Se uma biblioteca instalada pelo usuário existente usa o mesmo pacote Python que uma biblioteca criada por você, é necessário remover a biblioteca existente antes de instalar a nova biblioteca. 

Você deve ser um superusuário ou ter privilégio `USAGE ON LANGUAGE plpythonu` para instalar bibliotecas personalizadas; entretanto, qualquer usuário com privilégios suficientes para criar funções pode usar as bibliotecas instaladas. Você pode consultar o catálogo de sistema [PG\$1LIBRARY](r_PG_LIBRARY.md) para visualizar informações sobre as bibliotecas instaladas em seu cluster.

## Importar um módulo Python personalizado para o cluster
<a name="udf-import-custom-python-module-procedure"></a>

Esta seção fornece um exemplo de importação de um módulo Python personalizado para o seu cluster. Para executar as etapas desta seção, você deve ter um bucket do Amazon S3, onde você carrega o pacote de biblioteca. Então, você instala o pacote em seu cluster. Para obter mais informações sobre como criar buckets, consulte [ Criar um bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingaBucket.html) no *Guia do usuário do Amazon Simple Storage Service*.

Neste exemplo, suponhamos que você crie UDFs para trabalhar com posições e distâncias em seus dados. Conecte-se ao seu cluster Amazon Redshift a partir de uma ferramenta de cliente SQL e execute os comandos a seguir para criar as funções. 

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

Observe que algumas linhas de código estão duplicadas nas funções anteriores. Essa duplicação é necessária pois uma UDF não pode fazer referência ao conteúdo de outra UDF e ambas as funções exigem a mesma funcionalidade. Contudo, em vez de duplicar o código em várias funções, você pode criar uma biblioteca personalizada e configurar as funções para usá-la. 

Para fazer isso, crie o pacote da biblioteca seguindo estas etapas: 

1. Crie uma pasta chamada **geometry**. Essa pasta é o pacote de nível superior da biblioteca.

1. Na pasta **geometry**, crie um arquivo chamado `__init__.py`. Observe que o nome do arquivo contém dois caracteres duplos de sublinhado. Este arquivo indica para Python que o pacote pode ser inicializado.

1. Também na pasta **geometry**, crie uma pasta chamada **trig**. Essa pasta é o subpacote da biblioteca.

1. Na pasta **trig**, crie outro arquivo chamado `__init__.py` e um arquivo chamado `line.py`. Nesta pasta, `__init__.py` indica a Python que o subpacote pode ser inicializado e que `line.py` é o arquivo que contém o código da biblioteca.

   Suas pasta e estrutura de arquivo devem ser exatamente como se segue: 

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

    Para mais informações sobre a estrutura de pacotes, acesse [ Módulos](https://docs.python.org/2/tutorial/modules.html) no tutorial na página da Python. 

1.  O seguinte código contém uma classe e funções de membro para a biblioteca. Copie-o e cole-o em `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)
   ```

 Depois de criar o pacote, faça como mostrado a seguir para preparar o pacote e carregá-lo no Amazon S3. 

1. Comprima o conteúdo da pasta **geometry** em um arquivo de .zip chamado **geometry.zip.** Não inclua a própria pasta **geometry**; inclua somente os conteúdo da pasta, conforme mostrado a seguir: 

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

1. Carregue **geometry.zip** para o seu bucket do Amazon S3.
**Importante**  
 Se o bucket do Amazon S3 não residir na mesma região que seu cluster do Amazon Redshift, você deve usar a opção REGION para especificar a região na qual os dados estão localizados. Para obter mais informações, consulte [CREATE LIBRARY](r_CREATE_LIBRARY.md).

1.  A partir de sua ferramenta do cliente SQL, execute o seguinte comando para instalar a biblioteca. Substitua *<bucket\$1name>* pelo nome do bucket e *<access key id>* e *<secret key>* por uma chave de acesso e chave de acesso secreta de suas credenciais de usuário do 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>';
   ```

 Após instalar a biblioteca em seu cluster, você precisará configurar suas funções para que usem a biblioteca. Para fazer isso, execute os comandos a seguir. 

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

Nos comandos anteriores, `import trig/line` elimina o código duplicado das funções originais nesta seção. Você pode reutilizar a funcionalidade fornecida por essa biblioteca em várias UDFs. Observe que para importar o módulo, você somente precisa especificar o caminho para o subpacote e nome do módulo (`trig/line`). 

# Restrições de UDFs do Python
<a name="udf-constraints"></a>

Dentro das restrições listadas neste tópico, você pode usar UDFs em qualquer lugar em que usar as funções escalares integradas do Amazon Redshift. Para obter mais informações, consulte [Referência de funções SQL](c_SQL_functions.md).

As UDFs do Amazon Redshift Python têm as seguintes restrições:
+ As UDFs Python não podem acessar a rede nem ler ou gravar o sistema de arquivos.
+ O tamanho total das bibliotecas Python instaladas pelo usuário não pode exceder 100 MB.
+ O Amazon Redshift só pode executar uma UDF Python por vez para clusters provisionados usando o gerenciamento de workload (WLM) automático e para grupos de trabalho de tecnologia sem servidor. Se você tentar executar mais de uma UDF simultaneamente, o Amazon Redshift enfileirará as UDFs restantes do Python para serem executadas nas filas de gerenciamento de workload. As UDFs SQL não têm um limite de simultaneidade ao usar o WLM automático. 
+  Ao usar o WLM manual para clusters provisionados, o número de UDFs Python que podem ser executadas simultaneamente por cluster é limitado a um quarto do nível total de simultaneidade do cluster. Por exemplo, um cluster provisionado com uma simultaneidade de 15 pode executar no máximo três UDFs Python simultâneas. 
+ Ao usar UDFs Python, o Amazon Redshift não oferece suporte aos tipos de dados SUPER e HLLSKETCH.

# Registro em log de erros e alertas em UDFs do Python
<a name="udf-logging-messages"></a>

Você pode usar o módulo de log Python para criar mensagens de erro e alerta definidas pelo usuário em suas UDFs. Depois da execução da consulta, você poderá consultar a exibição do sistema [SVL\$1UDF\$1LOG](r_SVL_UDF_LOG.md) para recuperar mensagens registradas.

**nota**  
O log de UDF consome recursos do cluster e pode afetar a performance do sistema. Recomendamos a implementação de log somente para desenvolvimento e solução de problemas. 

Durante a execução da consulta, o handler do log grava mensagens na exibição de sistema de SVL\$1UDF\$1LOG, assim como o nome da função, nó e fatia correspondentes. O handler do log grava uma linha no SVL\$1UDF\$1LOG por mensagem e por fatia. As mensagens são truncadas para 4.096 bytes. O log da UDF é limitado a 500 linhas por fatia. Quando o log fica cheio, o handler do log descarta as mensagens mais antigas e adiciona uma mensagem de alerta em SVL\$1UDF\$1LOG.

**nota**  
O manipulador de log UDF do Amazon Redshift escapa caracteres de nova linha (`\n` ), barra vertical (`|`) e barra invertida (`\`) com um caractere barra invertida (`\`).

Por padrão, o nível de log de UDF é definido como WARNING. As mensagens com um nível de log WARNING, ERROR e CRITICAL são registradas. As mensagens com problemas de segurança INFO, DEBUG e NOTSET são ignoradas. Ao definir o nível de log de UDF, use o método do registrador Python. Por exemplo, defina o nível de log como INFO da forma a seguir.

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

Para mais informações sobre como usar o módulo de registro Python, consulte [Instalação de registro para Python](https://docs.python.org/2.7/library/logging.html) na documentação Python.

O exemplo a seguir cria uma função chamada f\$1pyerror que importa o módulo de log Python, instancia o registrador e registra um erro.

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

O exemplo a seguir consulta SVL\$1UDF\$1LOG para visualizar a mensagem registrada no exemplo anterior.

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