すべてのプロダクト
Search
ドキュメントセンター

Realtime Compute for Apache Flink:Python UDTF

最終更新日:Sep 24, 2026

このトピックでは、Python ユーザー定義テーブル関数 (UDTF) の開発、登録、使用方法について説明します。

定義

ユーザー定義テーブル関数 (UDTF) は、0 個、1 個、または複数のスカラー値を入力パラメーターとして受け取ります。これらのパラメーターは可変長です。スカラー関数とは異なり、UDTF は単一の値ではなく、任意の数の行を返すことができます。返される各行には 1 つ以上の列を含めることができ、UDTF の各呼び出しで複数の行または列を出力できます。

制限事項

Realtime Compute for Apache Flink のデプロイおよびネットワーク環境の特性上、Python ユーザー定義関数を開発する際には、以下の制限事項にご注意ください。

  • オープンソース Flink V1.12 以降のみをサポートしています。

  • Python は Flink ワークスペースにプリインストールされています。プリインストールされた Python バージョンでコードを開発してください。

注記

VVR 8.0.11 より前の Realtime Compute エンジンには Python 3.7.9 がプリインストールされており、VVR 8.0.11 以降には Python 3.9.19 がプリインストールされています。以前のバージョンから VVR 8.0.11 以降にアップグレードする場合は、以前のバージョンで開発された PyFlink ジョブを再テスト、デプロイ、実行する必要があります。

  • Flink ランタイムは JDK 8 および JDK 11 のみをサポートしています。Python ジョブがサードパーティの JAR パッケージに依存する場合は、JAR パッケージに互換性があることを確認してください。

  • オープンソース Scala V2.11 のみをサポートしています。Python ジョブがサードパーティの JAR パッケージに依存する場合は、Scala V2.11 に対応する JAR パッケージを使用してください。

  • インライン関数は、VVR 6.0.0 以降でのみサポートされます。

UDTF の開発

Python 関数は、以下のいずれかの方法で開発できます。

  • Python コードをパッケージ化してアップロードし、プラットフォームでコードを登録します。

  • SQL スクリプト内でコードロジックをインライン関数として宣言します。

UDTF のロジックが単純な場合は、Python 関数をインライン関数として開発できます。

コードパッケージを使用した UDTF の開発

UDTF の開発

注記

Flink は、UDX の開発を支援するために、Python ユーザー定義拡張 (UDX) のサンプルプロジェクトを提供しています。サンプルには、Python ユーザー定義スカラー関数、ユーザー定義集計関数 (UDAF)、および UDTF の実装が含まれています。この例では、Windows オペレーティングシステムを使用して UDTF を開発する方法について説明します。

重要

  • 登録する UDF 名には、小文字、数字、ハイフン (-) のみを使用できます。アンダースコア (_) やその他の特殊文字は使用できません。

  • Realtime Compute for Apache Flink のマネージド環境には、split のような組み込み関数がいくつかプリインストールされています。カスタム関数が組み込み関数と同じ名前の場合、登録に失敗するか、SQL 検証でエラーが発生します。関数名には、my-split のようなカスタムプレフィックスを使用してください。

  1. python_demo-master サンプルパッケージをダウンロードし、コンピューターに解凍します。

  2. PyCharm で、[file] > [open] を選択して、解凍した python_demo-master フォルダーを開きます。

  3. \python_demo-master\udx\udtfs.py をダブルクリックし、ビジネス要件に基づいて udtfs.py ファイルの内容を変更します。

この例では、my_split は各行の文字列を縦棒 (|) で複数の列に分割します。


    from pyflink.table import DataTypes
    from pyflink.table.udf import udtf
    
    @udtf(result_types=[DataTypes.STRING(), DataTypes.STRING()])
    def my_split(s: str):
        splits = s.split("|")
        yield splits[0], splits[1]
        
  1. ダウンロードしたパッケージ (\python_demo) 内の udx フォルダーが含まれているディレクトリで、以下のコマンドを実行してファイルをパッケージ化します。


    zip -r python_demo.zip udx
        

\python_demo\ ディレクトリに python_demo.zip パッケージが生成されると、UDTF の開発は完了です。

UDTF の登録

UDTF の登録方法の詳細については、「UDF の管理」をご参照ください。

UDTF の使用

UDTF が登録されると、使用できるようになります。以下の手順を実行してください。

  1. Flink SQL ジョブを開発します。詳細については、「ジョブ開発の概要」をご参照ください。

ASI_UDTF_Source テーブルの各行の message フィールドの値は、文字列 aa と縦棒 (|) で連結された後、さらに縦棒 (|) で複数の列に分割されます。


    CREATE TEMPORARY TABLE ASI_UDTF_Source (
      `message`  VARCHAR
    ) WITH (
      'connector'='datagen'
    );
    
    CREATE TEMPORARY TABLE ASI_UDTF_Sink (
      name  VARCHAR,
      place  VARCHAR
    ) WITH (
      'connector' = 'blackhole'
    );
    
    INSERT INTO ASI_UDTF_Sink
    SELECT name,place
    FROM ASI_UDTF_Source,lateral table(my_split(concat_ws('|', `message`, 'aa'))) as T(name,place);
        
  1. [O&M] > [Deployments] ページで、対象ジョブの [Actions] 列にある [Start] をクリックします。

ジョブが開始されると、ASI_UDTF_Sink テーブルには 2 つの列が含まれます。このデータは、ASI_UDTF_Source テーブルの各行の message フィールドと aa フィールドを縦棒 (|) で連結し、その結果を縦棒 (|) で分割して生成されます。

Python インラインテーブル関数

インライン関数は、CREATE FUNCTION ステートメント内に関数の実装を直接埋め込みます。関数の定義と登録宣言は、同じ SQL ステートメント内で完了します。以下の例では、注文商品を解析するインライン関数を定義します。$$ の間に完全なコードロジックを宣言する必要があります。

CREATE TEMPORARY FUNCTION parse_order_items(items_json STRING)
RETURNS TABLE (
    sku STRING,
    quantity INT
)
HANDLER 'ParseOrderItems'
AS $$
import json

class ParseOrderItems:
    def eval(self, items_json):
        if not items_json:
            return

        try:
            items = json.loads(items_json)
        except (TypeError, ValueError):
            return

        if not isinstance(items, list):
            return

        for item in items:
            if not isinstance(item, dict):
                continue

            sku = str(item.get("sku", "")).strip().upper()

            try:
                quantity = int(item.get("quantity"))
            except (TypeError, ValueError):
                continue

            if sku and quantity > 0:
                yield sku, quantity
$$
LANGUAGE PYTHON;
説明
  1. Python ではインデントが重要です。関数本体の第 1 レベルのコードは行頭に記述し、コードブロック内の相対的なインデントが正しいことを確認してください。

  2. インライン関数はベクトル化実行をサポートしておらず、非決定性関数として宣言することもできません。

  3. 一時関数のみ作成できます。