Exemplo: importar módulos personalizados da biblioteca Python
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_LIBRARY para visualizar informações sobre as bibliotecas instaladas em seu cluster.
Importar um módulo Python personalizado para o cluster
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 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:
-
Crie uma pasta chamada geometry. Essa pasta é o pacote de nível superior da biblioteca.
-
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. -
Também na pasta geometry, crie uma pasta chamada trig. Essa pasta é o subpacote da biblioteca.
-
Na pasta trig, crie outro arquivo chamado
__init__.py
e um arquivo chamadoline.py
. Nesta pasta,__init__.py
indica a Python que o subpacote pode ser inicializado e queline.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
no tutorial na página da Python. -
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.
-
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
-
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 ter mais informações, consulte CREATE LIBRARY.
-
A partir de sua ferramenta do cliente SQL, execute o seguinte comando para instalar a biblioteca. Substitua
<bucket_name>
pelo nome do seu bucket e substitua<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
).