メニュー
Amazon Redshift
データベース開発者ガイド (API Version 2012-12-01)

UDF のための Python 言語のサポート

Python プログラミング言語に基づいてカスタム UDF を作成できます。Python 2.7 標準ライブラリは UDF で使用できますが、以下のモジュールは例外です。

  • ScrolledText

  • Tix

  • Tkinter

  • tk

  • turtle

  • smtpd

Python 標準ライブラリに加え、以下のモジュールも Amazon Redshift 実装の一部です。

独自のカスタム Python モジュールをインポートし、ライブラリを作成する コマンドを実行することによって UDF で使用できるようにすることも可能です。詳細については、「カスタム Python ライブラリモジュールのインポート」を参照してください。

重要

Amazon Redshift は、UDF を介したすべてのネットワークアクセスとファイルシステムへの書き込みアクセスをブロックします。

カスタム Python ライブラリモジュールのインポート

スカラー関数は、Python 言語構文を使用して定義します。ネイティブの Python 標準ライブラリモジュールと Amazon Redshift が事前にインストールしたモジュールに加え、独自のカスタム Python ライブラリモジュールを作成してクラスターにインポートできるほか、Python またはサードパーティ提供の既存のライブラリを使用することもできます。

Python 標準ライブラリモジュール、またはインストール済みの Amazon Redshift Python モジュールと同じ名前のモジュールを含むライブラリを作成することはできません。 ユーザーがインストールした既存のライブラリが独自に作成するライブラリと同じ Python パッケージを使用している場合は、新しいライブラリをインストールする前に既存のライブラリを削除する必要があります。

カスタムライブラリをインストールするには、スーパーユーザーであるか、USAGE ON LANGUAGE plpythonu 権限を持っている必要がありますが、関数を作成するために十分な権限を持っているすべてのユーザーが、インストールされているライブラリを使用できます。PG_LIBRARY システムカタログをクエリすることによって、クラスターにインストールされているライブラリに関する情報を確認できます。

注記

Amazon Redshift では、Microsoft Windows からの Python モジュールのインポートはサポートされていません。

カスタム Python モジュールをクラスターにインポートするには

このセクションでは、カスタム Python モジュールをクラスターにインポートする例を示します。このセクションの手順を実行するには、ライブラリパッケージをアップロードする Amazon S3 バケットを準備する必要があります。その後に、パッケージをクラスターにインストールします。バケットの作成の詳細については、Amazon Simple Storage Service コンソールユーザーガイド の「バケットの作成」を参照してください。

この例では、データ内の位置と距離を操作する UDF を作成するとします。SQL クライアントツールから Amazon Redshift クラスターに接続し、以下のコマンドを実行して関数を作成します。

Copy
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 という名前のファイルを作成します。このファイル名には 2 つの二重下線文字が含まれています。このファイルは、パッケージが初期化可能であることを Python に対して示します。

  3. geometry フォルダーに trig という名前のフォルダーを作成します。このフォルダーはライブラリのサブパッケージです。

  4. trig フォルダーに __init__.py ファイルをもう 1 つ作成し、line.py という名前のファイルを作成します。このフォルダー内の __init__.py は、サブパッケージが初期化可能であり、line.py がライブラリコードを含んでいるファイルであることを Python に対して示します。

    フォルダーとファイルの構造は、次のような構造でなければなりません。

    Copy
    geometry/ __init__.py trig/ __init__.py line.py
    パッケージの構造の詳細については、Python ウェブサイトに掲載されている Python チュートリアルの「モジュール」を参照してください。

  5. 次のコードにはライブラリのクラスとメンバー関数が含まれています。これをコピーし、line.py に貼り付けます。

    Copy
    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 フォルダー自体はこれに含めないでください。次に示すように、このフォルダーの内容のみを含めます。

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

  2. geometry.zip を Amazon S3 バケットにアップロードします。

  3. SQL クライアントツールから次のコマンドを実行してライブラリをインストールします。<bucket_name> をバケットの名前に置き換え、<access key id><secret key> をそれぞれ AWS Identity and Access Management (IAM) ユーザー認証情報のアクセスキーとシークレットアクセスキーに置き換えます。

    Copy
    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>';

クラスターにライブラリをインストールしたら、関数がライブラリを使用するように設定する必要があります。これを行うには、以下のコマンドを実行します。

Copy
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)。