

 Amazon Redshift 將不再支援從修補程式 198 開始建立新的 Python UDFs。現有 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/)。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 範例：匯入自訂 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 模組匯入至您的叢集的範例。若要執行本節中的步驟，您必須具有 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)
   ```

 在您建立了套件之後，請執行下列動作，來準備套件並將其上傳至 Amazon S3。

1. 將 **geometry** 資料夾的內容壓縮成名為 **geometry.zip** 的 .zip 檔案。不要包括 **geometry** 資料夾本身；只包括資料夾的內容，如下所示：

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

1. 將 **geometry.zip** 上傳至您的 Amazon S3 儲存貯體。
**重要**  
 如果 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`)。