UDF のための Python 言語のサポート - Amazon Redshift

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

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

  • ScrolledText

  • Tix

  • Tkinter

  • tk

  • turtle

  • smtpd

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

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

重要

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

注記

Python 3 は Python UDF では使用できません。Amazon Redshift UDF に対する Python 3 のサポートを取得するには、スカラー Lambda UDF の作成 を代わりに使用します。

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

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

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

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

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

このセクションでは、カスタム Python モジュールをクラスターにインポートする例を示します。このセクションの手順を実行するには、ライブラリパッケージをアップロードする 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 という名前のファイルを作成します。このファイル名には 2 つの二重下線文字が含まれています。このファイルは、パッケージが初期化可能であることを Python に対して示します。

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

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

    フォルダとファイル構造は、次のようにする必要があります。

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

    パッケージ構造についての詳細は、Python ウェブサイトの Python チュートリアルの「Modules」を参照してください。

  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)

パッケージの作成が完了したら、次の手順に従ってパッケージを準備し、Amazon S3 にアップロードします。

  1. geometry フォルダの内容を圧縮して geometry.zip という名前の .zip ファイルを作成します。geometry フォルダ自体はこれに含めないでください。次に示すように、このフォルダの内容のみを含めます。

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

    重要

    Amazon S3 バケットが Amazon Redshift クラスターと同じリージョンに存在しない場合は、REGION オプションを使用して、データがあるリージョンを指定する必要があります。詳細については、「ライブラリを作成する」を参照してください。

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