MaxComputeで使用されるPython 2のバージョンは、Python 2.7です。 このトピックでは、Python 2でユーザー定義のテーブル値関数 (UDTF) を記述する方法について説明します。
UDTFコード構造
MaxCompute Studioを使用して、Python 2でUDTFコードを記述できます。 UDTFコードには、次の情報を含める必要があります。
エンコーディング宣言: オプション。
宣言形式は、
#coding: utf-8または# -*- coding: utf-8 -*-です。 2つの形式は同等です。 Python 2で記述されたUDTFコードに漢字が表示される場合、UDTFを実行するとエラーが返されます。 この問題を解決するには、コードのヘッダーにエンコード宣言を追加する必要があります。モジュールのインポート: 必須。
UDTFコードには、
from odps.udf import annotateとfrom odps.udf import BaseUDTFを含める必要があります。from odps.udf import annotateは、関数署名モジュールをインポートするために使用されます。 これにより、MaxComputeはコードで定義されている関数シグネチャを識別できます。from odps.udf import BaseUDTFは、Python UDTFの基本クラスです。 このクラスを使用して、派生クラスにprocessやcloseなどのメソッドを実装する必要があります。UDTFコードでファイルまたはテーブルを参照する場合は、UDTFコードに
from odps.distcache import get_cache_fileまたはfrom odps.distcache import get_cache_tableを含める必要があります。関数署名: オプション。
関数シグネチャは、
@ annotate(<signature>)形式です。signatureパラメーターは、UDTFの入力パラメーターと戻り値のデータ型を定義するために使用されます。 関数シグネチャを指定しない場合、SQL文でUDTFを呼び出すときに、任意のデータ型の入力パラメーターを一致させることができます。 その結果、戻り値のデータ型は推論できず、すべての出力パラメーターはSTRING型になります。 関数シグネチャの詳細については、「関数シグネチャとデータ型」をご参照ください。カスタムPythonクラス (派生クラス): 必須です。
カスタムPythonクラスは、UDTFコードの組織単位です。 このクラスは、ビジネス要件を満たすために使用される変数とメソッドを定義します。 UDTFコードでは、MaxComputeに構築されているサードパーティライブラリを参照したり、ファイルやテーブルを参照したりできます。 詳細については、「サードパーティライブラリ」または「リソースリファレンス」をご参照ください。
Pythonクラスを実装するメソッド: required.
Pythonクラスを実装するには、4つのメソッドを使用できます。 これらのメソッドを次の表に示します。
移動方法
説明
BaseUDTF.init()初期化メソッド。 このメソッドを派生クラスに実装するには、コードの実行を開始するときに、基本クラスの
super(BaseUDTF, self).init()初期化メソッドを呼び出す必要があります。INITメソッドは、UDTFのライフサイクル全体で1回だけ呼び出されます。 このメソッドは、最初のレコードが処理される前にのみ呼び出されます。 UDTFが内部状態を保存する必要がある場合、この方法を使用してすべての状態を初期化できます。BaseUDTF.process([args, ...])process関数は、SQLレコードごとに1回呼び出されます。process関数のパラメーターは、SQL文で指定されたUDTFの入力パラメーターです。BaseUDTF.forward([args, ...])UDTFの出力メソッド。 このメソッドはユーザーコードによって呼び出されます。
forwardメソッドが呼び出されるたびに1つの出力レコードが生成されます。forwardメソッドのパラメーターは、SQL文で指定されたUDTF出力パラメーターです。Pythonコードで関数シグネチャが指定されていない場合、
forwardメソッドが呼び出されるときにすべての出力値をSTRING型に変換する必要があります。BaseUDTF.close()UDTFを終了するメソッド。 このメソッドは一度だけ呼び出されます。 最後のレコードが処理される前にのみ呼び出されます。
次の例は、UDTFコードを示しています。
#coding:utf-8
# Import the function signature module and the base class.
from odps.udf import annotate
from odps.udf import BaseUDTF
# The function signature.
@annotate('string -> string')
# The custom Python class.
class Explode(BaseUDTF):
# Methods used to implement Python classes.
def process(self, arg):
props = arg.split(',')
for p in props:
self.forward(p)制限事項
MaxComputeでは、Python 2.7でPython 2 UDTFを記述し、サンドボックス環境でUDTFコードを実行できます。 この環境では、以下の操作は禁止されています。
ローカルファイルからデータを読み取り、データを書き込みます。
サブプロセスを開始します。
スレッドを開始します。
ソケット通信を有効にします。
他のシステムを使用して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は関数署名文字列です。 このパラメーターは、入力パラメーターと戻り値のデータ型を識別するために使用されます。 UDTFを実行する場合、UDTFの入力パラメーターと戻り値は、関数シグネチャで指定されたものと同じデータ型である必要があります。 データ型の整合性は、セマンティック解析中にチェックされます。 データ型に矛盾がある場合は、エラーが返されます。 署名の形式は次のとおりです。
'arg_type_list -> type_list'パラメーターの説明:
type_list: 戻り値のデータ型を示します。 UDTFは複数の列を返すことができます。 BIGINT、STRING、DOUBLE、BOOLEAN、DATETIME、DECIMAL、FLOAT、BINARY、DATE、DECIMAL(precision、scale) のデータ型がサポートされています。 ARRAY、MAP、STRUCTなどの複雑なデータ型、およびネストされた複雑なデータ型もサポートされています。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が空 ('') の場合、入力パラメーターは使用されません。
@ Resolveアノテーションの構文拡張機能の詳細については、「UDAFおよびUDTFの動的パラメーター」をご参照ください。
UDTFコードを記述するときは、MaxComputeプロジェクトのデータ型エディションに基づいてデータ型を選択できます。 データ型のエディションと各エディションでサポートされているデータ型の詳細については、「データ型のエディション」をご参照ください。
次の表に、有効な関数シグネチャの例を示します。
関数署名 | 説明 |
| 入力パラメーターのデータ型はBIGINTとBOOLEANです。 戻り値のデータ型はSTRINGとDATETIMEです。 |
| ランダムな数の入力パラメーターが使用され、戻り値のデータ型はSTRINGとDATETIMEです。 |
| 入力パラメーターは使用されず、戻り値のデータ型はDOUBLE、BIGINT、STRINGです。 |
| 入力パラメータのデータ型は、ARRAY、STRUCT、およびMAPである。 戻り値のデータ型はMAPとSTRUCTです。 |
次の表に、MaxCompute SQLでサポートされているデータ型とPython 2データ型の間のマッピングを示します。 データ型の一貫性を確保するには、マッピングに基づいてPython UDTFを記述する必要があります。
MaxCompute SQLデータ型 | Python 2データ型 |
BIGINT | INT |
STRING | STR |
DOUBLE | FLOAT |
BOOLEAN | BOOL |
日付時刻 | 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 UDTFでファイルとテーブルを参照できます。
odps.distcache.get_cache_file(resource_name): 特定のファイルの内容を返します。resource_nameは、MaxComputeプロジェクト内の既存のファイルの名前を指定する文字列です。 ファイル名が無効であるか、ファイルが存在しない場合は、エラーが返されます。説明UDTF内のファイルを参照するには、UDTFを作成するときにファイルリソースを宣言する必要があります。 それ以外の場合、UDTFが呼び出されるとエラーが返されます。
戻り値はファイルのようなオブジェクトです。 このオブジェクトが使用されなくなった場合は、
closeメソッドを呼び出して開いているファイルを解放する必要があります。
odps.distcache.get_cache_table(resource_name): 指定されたテーブルの内容を返します。resource_nameは、MaxComputeプロジェクト内の既存のテーブルの名前を指定する文字列です。 テーブル名が無効であるか、テーブルが存在しない場合は、エラーが返されます。戻り値はジェネレータ型です。 呼び出し元はテーブルをトラバースしてコンテンツを取得します。 呼び出し元がテーブルをトラバースするたびに、ARRAYタイプのレコードが生成されます。
次のサンプルコードは、ファイルとテーブルを参照する方法を示しています。
# -*- coding: utf-8 -*-
from odps.udf import annotate
from odps.udf import BaseUDTF
from odps.distcache import get_cache_file
from odps.distcache import get_cache_table
@annotate('string -> string, bigint')
class UDTFExample(BaseUDTF):
"""Read pageid and adid in the file and table to generate dict.
"""
def __init__(self):
import json
cache_file = get_cache_file('test_json.txt')
self.my_dict = json.load(cache_file)
cache_file.close()
records = list(get_cache_table('table_resource1'))
for record in records:
self.my_dict[record[0]] = [record[1]]
"""Enter pageid and generate pageid and all adid values.
"""
def process(self, pageid):
for adid in self.my_dict[pageid]:
self.forward(pageid, adid)使用上の注意
概要の手順に従ってPython 2 UDTFを開発した後、MaxCompute SQLを使用してPython 2 UDTFを呼び出すことができます。 次の手順では、Python 2 UDTFを呼び出す方法について説明します。
MaxComputeプロジェクトでUDFを使用する: この方法は、組み込み関数を使用する方法と似ています。
プロジェクト間でUDFを使用する: プロジェクトaでプロジェクトBのUDFを使用します。次のステートメントは、例を示します。
select B:udf_in_other_project(arg0, arg1) as res from table_t;プロジェクト間共有の詳細については、「パッケージに基づくプロジェクト間リソースアクセス」をご参照ください。
MaxCompute Studioを使用してPython 2 UDTFを開発および呼び出す方法の詳細については、「Python UDFの開発」をご参照ください。