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

MaxCompute:Python 2でUDFを開発する

最終更新日:Jan 06, 2025

MaxComputeで使用されるPython 2のバージョンは、Python 2.7です。 このトピックでは、Python 2でユーザー定義関数 (UDF) を記述する方法について説明します。

UDFコード構造

MaxCompute Studioを使用して、Python 2でUDFコードを記述できます。 UDFコードには、次の情報を含めることができます。

  • エンコーディング宣言: オプション。

    宣言形式は、#coding: utf-8または# -*- coding: utf-8 -*- です。 2つの形式は同等です。 Python 2で記述されたUDFコードに漢字が表示される場合、UDFを実行するとエラーが返されます。 この問題に対処するには、コードのヘッダーにエンコード宣言を追加する必要があります。

  • モジュールのインポート: 必須。

    UDFコードには、関数シグネチャのインポートに使用されるfrom odps.udf import annotateを含める必要があります。 これにより、MaxComputeはコードで定義されている関数シグネチャを識別できます。 UDFコードでファイルまたはテーブルを参照する場合は、UDFコードにfrom odps.distcache import get_cache_fileまたはfrom odps.distcache import get_cache_tableを含める必要があります。

  • 関数署名: 必須。

    関数シグネチャは、@ annotate(<signature>) 形式です。 signatureパラメーターは、入力パラメーターのデータ型とUDFの戻り値を定義するために使用されます。 関数シグネチャの詳細については、「関数シグネチャとデータ型」をご参照ください。

  • カスタムPythonクラス: required。

    カスタムPythonクラスは、UDFコードの組織単位です。 このクラスは、ビジネス要件を満たすために使用される変数とメソッドを定義します。 UDFコードでは、MaxComputeにインストールされているサードパーティライブラリを参照したり、ファイルやテーブルを参照したりすることもできます。 詳細については、「サードパーティライブラリ」または「リファレンスリソース」をご参照ください。

  • メソッドevaluate: 必須。

    evaluateメソッドは、カスタムPythonクラスに含まれています。 evaluateメソッドは、UDFの入力パラメーターと戻り値を定義します。 各Pythonクラスにevaluateメソッドを1つだけ含めることができます。

サンプルコード:

#coding:utf-8
# Import the function signature. 
from odps.udf import annotate
# The function signature. 
@annotate("bigint,bigint->bigint")
# The custom Python class. 
class MyPlus(object):
# The evaluate method. 
   def evaluate(self, arg0, arg1):
       if None in (arg0, arg1):
           return None
       return arg0 + arg1

制限事項

MaxComputeでは、Python 2.7でPython 2 UDFを記述し、サンドボックス環境でUDFコードを実行できます。 この環境では、以下の操作は禁止されています。

  • ローカルファイルからデータを読み取り、データを書き込みます。

  • サブプロセスを開始します。

  • スレッドを開始します。

  • ソケット通信を有効にします。

  • 他のシステムを使用してPython 2 UDFを呼び出します。

これらの制限により、アップロードするコードはPython標準ライブラリを使用して記述する必要があります。 Python標準ライブラリのモジュールまたはC拡張モジュールが上記の操作に関与している場合、これらのモジュールは使用できません。 Python標準ライブラリのモジュールに関する次の点に注意してください。

  • Python標準ライブラリに基づいて実装され、拡張モジュールに依存しないすべてのモジュールが利用可能です。

  • 次のC拡張モジュールを使用できます。

    • arrayとaudioop

    • binasciiとbisect

    • cmath、_codecs_cn、_codecs_hk、_codecs_iso2022、_codecs_jp、_codecs_kr、_codecs_tw、_collections、およびcStringIO

    • datetime

    • _functoolsとfuture_builtins

    • _heapqおよび_hashlib

    • itertools

    • _json

    • _localeおよび_lsprof

    • math、_md5、および_multibytecodec

    • operator

    • _ランダム

    • _sha256、_sha512、_sha、_struct、およびstrop

    • time

    • unicodedata

    • _weakref

    • cPickle

  • サンドボックス環境でUDFコードを実行する場合、標準出力 (sys.stdout) または標準エラー出力 (sys.stderr) に書き込むことができるデータの最大サイズは20 KBです。 サイズが20 KBを超える場合、余分な文字は無視されます。

サードパーティライブラリ

NumPyなどのサードパーティライブラリは、標準ライブラリの補足としてMaxComputeのPython 2環境にインストールされます。

説明

サードパーティのライブラリの使用には、いくつかの制限があります。 たとえば、サードパーティのライブラリを使用する場合、ローカルデータへのアクセスは許可されず、限られたネットワークI/Oリソースしか使用できません。 サードパーティライブラリの関連APIは無効になっています。

関数シグネチャとデータ型

関数シグネチャの形式:

@annotate(<signature>)

signatureパラメーターは、入力パラメーターと戻り値のデータ型を指定する文字列です。 UDFを実行する場合、UDFの入力パラメーターと戻り値のデータ型は、関数シグネチャで指定されたデータ型と一致している必要があります。 データ型の整合性は、セマンティック解析中にチェックされます。 データ型に矛盾がある場合は、エラーが返されます。 署名の形式:

'arg_type_list -> type'

パラメーターの説明:

  • arg_type_list: 入力パラメーターのデータ型を指定します。 複数の入力パラメーターを使用する場合、データ型はコンマ (,) で区切ります。 BIGINT、STRING、DOUBLE、BOOLEAN、DATETIME、DECIMAL、FLOAT、BINARY、DATE、DECIMAL(precision、scale) 、CHAR、VARCHARのデータ型がサポートされています。 ARRAY、MAP、STRUCTなどの複雑なデータ型、およびネストされた複雑なデータ型もサポートされています。

    arg_type_listは、アスタリスク (*) または空のまま ('') で表すことができます。

    • arg_type_listがアスタリスク (*) で表される場合、ランダムな数の入力パラメーターが許可されます。

    • arg_type_listが空 ('') の場合、入力パラメーターは使用されません。

  • type: 戻り値のデータ型を指定します。 UDFの場合、値の1つの列のみが返されます。 BIGINT、STRING、DOUBLE、BOOLEAN、DATETIME、DECIMAL、FLOAT、BINARY、DATE、DECIMAL(precision、scale) のデータ型がサポートされています。 ARRAY、MAP、STRUCTなどの複雑なデータ型、およびネストされた複雑なデータ型もサポートされています。

説明

UDFコードを記述するときに、MaxComputeプロジェクトで使用されるMaxComputeデータ型エディションに基づいてデータ型を選択できます。 MaxComputeデータ型のエディションと各エディションでサポートされているデータ型の詳細については、「データ型のエディション」をご参照ください。

次の表に、有効な関数シグネチャの例を示します。

関数署名

説明

'bigint、double->string '

入力パラメーターのデータ型はBIGINTとDOUBLEで、戻り値のデータ型はSTRINGです。

'*->string'

ランダムな数の入力パラメーターが使用され、戻り値のデータ型はSTRINGです。

'-> double'

入力パラメーターは使用されず、戻り値のデータ型はDOUBLEです。

'array<bigint>->struct<x:string, y:int>'

入力パラメーターのデータ型はARRAY<BIGINT> 、戻り値のデータ型はSTRUCT<x:STRING, y:INT> です。

'->map<bigint, string>'

入力パラメーターは使用されず、戻り値のデータ型はMAP<BIGINT, STRING> です。

次の表に、MaxCompute SQLでサポートされているデータ型とPython 2データ型の間のマッピングを示します。 データ型の一貫性を確保するには、マッピングに基づいてPython UDFを記述する必要があります。

MaxCompute SQLデータ型

Python 2データ型

BIGINT

INT

STRING

STR

DOUBLE

FLOAT

BOOLEAN

BOOL

DATETIME

INT

FLOAT

FLOAT

CHAR

STR

VARCHAR

STR

BINARY

BYTEARRAY

DATE

INT

DECIMAL

DECIMAL.DECIMAL

ARRAY

LIST

MAP

DICT

STRUCT

COLLECTIONS.NAMEDTUPLE

説明
  • MaxCompute SQLでサポートされているDATETIME型は、Pythonデータ型INTにマップされます。 INT型の値は、1970年1月1日木曜日00:00:00から経過したミリ秒数です。 Python標準ライブラリのDATETIMEモジュールを使用して、DATETIME型のデータを処理できます。

  • silentパラメーターがodps.udf.int(value) に追加されます。 silentパラメーターがTrueに設定されていて、valueのデータ型をINT型に変換できない場合、Noneが返され、エラーは返されません。

  • MaxCompute SQLのNULLは、Python 2ではNoneにマップされます。

参照リソース

odps.distcacheモジュールを使用して、Python 2 UDFコードでファイルまたはテーブルを参照できます。

  • odps.distcache.get_cache_file(resource_name): 指定したファイルの内容を返します。

    • resource_nameは、MaxComputeプロジェクト内の既存のファイルの名前を指定する文字列です。 ファイル名が無効であるか、ファイルが存在しない場合は、エラーが返されます。

      説明

      UDFコードでファイルを参照するには、UDFを作成するときにファイルを宣言する必要があります。 それ以外の場合、UDFを呼び出すとエラーが返されます。

    • 戻り値はファイルのようなオブジェクトです。 このオブジェクトが使用されなくなった場合は、closeメソッドを呼び出して開いているファイルを解放する必要があります。

    ファイルを参照する方法を次のコードに示します。

    from odps.udf import annotate
    from odps.distcache import get_cache_file
    @annotate('bigint->string')
    class DistCacheExample(object):
    def __init__(self):
        cache_file = get_cache_file('test_distcache.txt')
        kv = {}
        for line in cache_file:
            line = line.strip()
            if not line:
                continue
            k, v = line.split()
            kv[int(k)] = v
        cache_file.close()
        self.kv = kv
    def evaluate(self, arg):
        return self.kv.get(arg)
  • odps.distcache.get_cache_table(resource_name): 指定されたテーブルの内容を返します。

    • resource_nameは、MaxComputeプロジェクト内の既存のテーブルの名前を指定する文字列です。 テーブル名が無効であるか、テーブルが存在しない場合は、エラーが返されます。

    • 戻り値はGENERATORデータ型です。 呼び出し元はテーブルをトラバースしてテーブルの内容を取得します。 ARRAYタイプのレコードは、呼び出し元がテーブルをトラバースするたびに取得されます。

    次のコードは、テーブルを参照する方法を示しています。

    from odps.udf import annotate
    from odps.distcache import get_cache_table
    @annotate('->string')
    class DistCacheTableExample(object):
        def __init__(self):
            self.records = list(get_cache_table('udf_test'))
            self.counter = 0
            self.ln = len(self.records)
        def evaluate(self):
            if self.counter > self.ln - 1:
                return None
            ret = self.records[self.counter]
            self.counter += 1
            return str(ret)

開発プロセス

UDFを開発するときは、準備を行い、UDFコードを記述し、Pythonプログラムをアップロードし、UDFを作成し、UDFをデバッグし、UDFを呼び出す必要があります。 MaxComputeでは、MaxCompute Studio、DataWorks、MaxComputeクライアント (odpscmd) など、複数のツールを使用してUDFを開発できます。

  • さまざまなツールを使用してPython 2でUDFを開発するプロセスは、Python 3でUDFを開発するプロセスと同じです。 開発プロセスの詳細とPythonでUDFを開発する方法の例については、「開発プロセス」をご参照ください。

  • MaxCompute Studioを使用してPython 2でUDFを開発および呼び出す方法の詳細については、「Python UDFの開発」をご参照ください。

使用上の注意

Python 2 UDFを開発した後、MaxCompute SQLを使用してこのUDFを呼び出すことができます。 次のいずれかの方法を使用して、Python 2 UDFを呼び出すことができます。

  • MaxComputeプロジェクトでUDFを使用する: この方法は、組み込み関数を使用する方法と似ています。

  • プロジェクト間でUDFを使用する: プロジェクトaでプロジェクトBのUDFを使用します。次のステートメントは、例を示します。select B:udf_in_other_project(arg0, arg1) as res from table_t; プロジェクト間共有の詳細については、「パッケージに基づくプロジェクト間リソースアクセス」をご参照ください。