适用于 UDF 的 Python 语言支持 - Amazon Redshift

适用于 UDF 的 Python 语言支持

您可以基于 Python 编程语言创建自定义 UDF。Python 2.7 标准库可以在 UDF 中使用,但以下模块除外:

  • ScrolledText

  • Tix

  • Tkinter

  • tk

  • turtle

  • smtpd

除 Python 标准库之外,以下模块也是 Amazon Redshift 实施的一部分:

您也可以通过执行 CREATE LIBRARY 命令来导入您自己的自定义 Python 模块并使其在 UDF 中可用。有关更多信息,请参阅 导入自定义 Python 库模块

重要

Amazon Redshift 将阻止通过 UDF 对文件系统进行的所有网络访问和写入访问。

注意

Python 3 不适用于 Python UDF。要获得 Python 3 对 Amazon Redshift UDF 的支持,请改用 创建标量 Lambda UDF

导入自定义 Python 库模块

您使用 Python 语言语法定义标量函数。您可以使用 Python 标准库模块和 Amazon Redshift 预安装的模块。您还可以创建您自己的自定义 Python 库模块并将这些库导入集群,或使用 Python 或第三方的现有库。

无法创建包含与 Python 标准库模块或 Amazon Redshift 预安装的 Python 模块同名的模块的库。如果现有用户安装的库使用与您创建的库相同的 Python 包,则必须先删除现有库,然后再安装新库。

您必须是超级用户或具有 USAGE ON LANGUAGE plpythonu 权限才能安装自定义库;不过,具有创建函数的足够权限的用户可以使用安装的库。您可以查询 PG_LIBRARY 系统目录以查看有关集群上安装的库的信息。

将自定义 Python 模块导入到集群

本部分提供了将自定义 Python 模块导入集群的示例。要执行本部分中的步骤,您必须拥有一个将库包上载到的 Simple Storage Service(Amazon S3)存储桶。然后将包安装到集群。有关创建存储桶的更多信息,请转至《Amazon Simple Storage Service 用户指南》中的创建存储桶

在此示例中,假设您创建 UDF 以使用数据中的位置和距离。从 SQL 客户端工具连接到您的 Amazon Redshift 集群,并运行以下命令以创建函数。

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;

请注意,前面的函数中复制了几行代码。此复制是必要的,因为 UDF 无法引用其他 UDF 的内容,并且这两个函数都需要相同的功能。但是,您可以创建自定义库并将函数配置为使用该库,而不是复制多个函数中的代码。

为此,首先请执行以下步骤来创建库包:

  1. 创建一个名为 geometry 的文件夹。此文件夹是库的顶级包。

  2. geometry 文件夹中,创建一个名为 __init__.py 的文件。请注意,该文件名包含两个下划线字符。此文件指示 Python 可初始化此包。

  3. 另外,在 geometry 文件夹中,创建一个名为 trig 的文件夹。此文件夹是库的子包。

  4. trig 文件夹中,创建另一个名为 __init__.py 的文件和一个名为 line.py 的文件。在此文件夹中,__init__.py 指示 Python 可以初始化子包,并且 line.py 是包含库代码的文件。

    您的文件夹和文件结构应类似于以下内容:

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

    有关包结构的更多信息,请参阅 Python 网站上的 Python 教程中的模块

  5. 以下代码包含库的类和成员函数。请将其复制并粘贴到 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)

在创建包之后,请执行以下操作以准备包并将其上载到 Simple Storage Service(Amazon S3)。

  1. geometry 文件夹的内容压缩到一个名为 geometry.zip 的 .zip 文件。请不要包括 geometry 文件夹本身;仅包括该文件夹的内容,如下所示:

    geometry.zip __init__.py trig/ __init__.py line.py
  2. geometry.zip 上载到您的 Simple Storage Service(Amazon S3)存储桶。

    重要

    如果 Simple Storage Service(Amazon S3)存储桶不在您的 Amazon Redshift 集群所在的区域内,则必须使用 REGION 选项指定数据所在的区域。有关更多信息,请参阅 CREATE LIBRARY

  3. 从您的 SQL 客户端工具运行以下命令可安装库。将 <bucket_name> 替换为您的存储桶的名称,并将 <access key id><secret key> 替换为您的 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>';

在集群中安装库后,您需要配置函数以使用库。为此,请运行以下命令。

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;

在前面的命令中,import trig/line 消除了本部分的原始函数中重复的代码。您可以在多个 UDF 中重复使用此库提供的功能。请注意,要导入模块,您只需指定到子包的路径和模块名称 (trig/line)。