

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# 适用于 UDF 的 Python 语言支持
<a name="udf-python-language-support"></a>

您可以基于 Python 编程语言创建自定义 UDF。[Python 2.7 标准库](https://docs.python.org/2/library/index.html)可以在 UDF 中使用，但以下模块除外：
+ ScrolledText
+ Tix
+ Tkinter
+ tk
+ turtle
+ smtpd

除 Python 标准库之外，以下模块也是 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)

您也可以通过执行 [CREATE LIBRARY](r_CREATE_LIBRARY.md) 命令来导入您自己的自定义 Python 模块并使其在 UDF 中可用。有关更多信息，请参阅 [示例：导入自定义 Python 库模块](udf-importing-custom-python-library-modules.md)。

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

**注意**  
Python 3 不适用于 Python UDF。要获得 Python 3 对 Amazon Redshift UDF 的支持，请改用 [标量 Lambda UDF](udf-creating-a-lambda-sql-udf.md)。

# 示例：导入自定义 Python 库模块
<a name="udf-importing-custom-python-library-modules"></a>

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

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

您必须是超级用户或具有 `USAGE ON LANGUAGE plpythonu` 权限才能安装自定义库；不过，具有创建函数的足够权限的用户可以使用安装的库。您可以查询 [PG\$1LIBRARY](r_PG_LIBRARY.md) 系统目录以查看有关集群上安装的库的信息。

## 将自定义 Python 模块导入到集群
<a name="udf-import-custom-python-module-procedure"></a>

本部分提供了将自定义 Python 模块导入集群的示例。要执行本部分中的步骤，您必须拥有一个将库包上载到的 Simple Storage Service（Amazon S3）存储桶。然后将包安装到集群。有关创建存储桶的更多信息，请转至《Amazon Simple Storage Service 用户指南》**中的[创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingaBucket.html)。

在此示例中，假设您创建 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** 的文件夹。此文件夹是库的顶级包。

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

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

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

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

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

    有关包结构的更多信息，请参阅 Python 网站上的 Python 教程中的[模块](https://docs.python.org/2/tutorial/modules.html)。

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

1. 将 **geometry.zip** 上载到您的 Simple Storage Service（Amazon S3）存储桶。
**重要**  
 如果 Simple Storage Service（Amazon S3）存储桶不在您的 Amazon Redshift 集群所在的区域内，则必须使用 REGION 选项指定数据所在的区域。有关更多信息，请参阅 [CREATE LIBRARY](r_CREATE_LIBRARY.md)。

1.  从您的 SQL 客户端工具运行以下命令可安装库。将 *<bucket\$1name>* 替换为存储桶的名称，并将 *<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`)。