All Products
Search
Document Center

MaxCompute:Python 3 UDAF

Last Updated:Aug 22, 2026

Python Software Foundation akan segera menghentikan pemeliharaan Python 2. MaxCompute kini mendukung Python 3, khususnya CPython-3.7.3. Topik ini menjelaskan cara menulis user-defined aggregate function (UDAF) dalam Python 3.

Struktur kode UDAF

Anda dapat menggunakan MaxCompute Studio untuk menulis kode user-defined aggregate function (UDAF) dalam Python 3. Kode tersebut harus mencakup informasi berikut:

  • Impor modul: Wajib.

    Anda harus mengimpor setidaknya from odps.udf import annotate dan from odps.udf import BaseUDAF. Pernyataan from odps.udf import annotate mengimpor modul signature fungsi, yang memungkinkan MaxCompute mengenali signature fungsi yang didefinisikan dalam kode. from odps.udf import BaseUDAF mengimpor kelas dasar untuk UDAF Python. Anda harus mengimplementasikan metode seperti iterate, merge, dan terminate dalam kelas turunan.

    Jika kode UDAF perlu mereferensi resource file atau tabel, sertakan from odps.distcache import get_cache_file untuk resource file atau from odps.distcache import get_cache_table untuk resource tabel.

  • Signature fungsi: Wajib.

    Formatnya adalah @annotate(<signature>). signature mendefinisikan tipe data parameter input dan nilai kembali fungsi. Untuk informasi lebih lanjut tentang signature fungsi, lihat Signature fungsi dan tipe data.

  • Kelas Python kustom (kelas turunan): Wajib.

    Kelas ini merupakan unit organisasi untuk kode UDAF. Kelas ini mendefinisikan variabel dan metode yang mengimplementasikan logika bisnis Anda. Anda juga dapat mereferensi pustaka pihak ketiga bawaan, file, atau resource tabel dalam kode Anda. Untuk informasi lebih lanjut, lihat Pustaka pihak ketiga atau Referensi resource.

  • Implementasi metode kelas Python: Wajib.

    Implementasi kelas Python mencakup metode-metode berikut. Anda dapat mengimplementasikan metode sesuai kebutuhan.

    Definisi metodeDeskripsi
    BaseUDAF.new_buffer()Mengembalikan buffer untuk nilai antara fungsi agregat. buffer harus berupa objek Marshal, seperti LIST atau DICT. Ukuran buffer tidak boleh meningkat seiring volume data. Dalam kasus ekstrem, ukuran buffer setelah serialisasi objek tidak boleh melebihi 2 MB.
    BaseUDAF.iterate(buffer[, args, ...])Mengagregasi args ke dalam nilai antara buffer.
    BaseUDAF.merge(buffer, pbuffer)Menggabungkan nilai antara buffer dan pbuffer serta menyimpan hasilnya di buffer.
    BaseUDAF.terminate(buffer)Mengonversi buffer menjadi tipe data primitif MaxCompute SQL.

Kode berikut memberikan contoh UDAF.

# Impor modul signature fungsi dan kelas dasar.
from odps.udf import annotate
from odps.udf import BaseUDAF
# Signature fungsi.
@annotate('double->double')
# Kelas Python kustom.
class Average(BaseUDAF):
# Implementasikan metode kelas Python.
    def new_buffer(self):
        return [0, 0]
    def iterate(self, buffer, number):
        if number is not None:
            buffer[0] += number
            buffer[1] += 1
    def merge(self, buffer, pbuffer):
        buffer[0] += pbuffer[0]
        buffer[1] += pbuffer[1]
    def terminate(self, buffer):
        if buffer[1] == 0:
            return 0.0
        return buffer[0] / buffer[1]
Gambar berikut menunjukkan logika implementasi dan alur perhitungan UDAF MaxCompute untuk menghitung nilai rata-rata (avg).求平均值逻辑pbuffer bersesuaian dengan pr pada gambar, dan buffer bersesuaian dengan r.
Catatan

Perbedaan antara UDAF Python 2 dan UDAF Python 3 terletak pada versi Python yang mendasarinya. Anda harus menulis UDAF berdasarkan kemampuan versi Python yang sesuai.

Catatan penggunaan

Python 3 tidak kompatibel dengan Python 2, dan keduanya tidak dapat digunakan dalam pernyataan SQL yang sama. Pertimbangkan kompatibilitas sebelum beralih.

Catatan

Python 2 telah mencapai akhir masa dukungan (EOL) pada awal 2020. Kami menyarankan Anda melakukan migrasi proyek berdasarkan jenisnya.

Migrasi UDAF Python 2

Python Software Foundation akan segera menghentikan pemeliharaan Python 2. Kami menyarankan Anda melakukan migrasi proyek berdasarkan jenis proyek:

  • Proyek baru: Berlaku untuk proyek MaxCompute baru atau proyek MaxCompute tempat Anda pertama kali menulis UDAF Python. Kami menyarankan Anda menulis semua UDAF Python dalam Python 3.

  • Proyek yang sudah ada: Berlaku untuk proyek MaxCompute yang memiliki banyak UDAF Python 2 yang sudah ada. Aktifkan Python 3 dengan hati-hati. Jika Anda berencana melakukan migrasi bertahap seluruh UDAF Python 2 ke Python 3, gunakan metode berikut:

    • Pekerjaan dan UDAF baru: Tulis dalam Python 3 dan aktifkan Python 3 pada tingkat session. Untuk informasi lebih lanjut tentang cara mengaktifkan Python 3, lihat Aktifkan Python 3.

    • UDAF Python 2: Tulis ulang UDAF Python 2 agar kompatibel dengan Python 2 dan Python 3. Untuk informasi lebih lanjut tentang cara menulis ulang kode, lihat Porting Python 2 Code to Python 3.

      Catatan

      Jika Anda ingin menulis UDAF publik dan memberikan izin kepada beberapa proyek MaxCompute untuk menggunakannya, kami menyarankan Anda membuat UDAF tersebut kompatibel dengan Python 2 dan Python 3.

Aktifkan Python 3

Secara default, MaxCompute menggunakan Python 2. Untuk menggunakan Python 3, sertakan flag session berikut dalam pernyataan SQL Anda.

set odps.sql.python.version=cp37;

Pustaka pihak ketiga

Lingkungan runtime Python 3 bawaan di MaxCompute tidak memiliki pustaka pihak ketiga NumPy yang terinstal. Untuk menggunakan UDAF yang memerlukan NumPy, Anda harus mengunggah paket WHEEL NumPy secara manual. Saat Anda mengunduh paket NumPy dari PyPI atau mirror-nya, nama file paket tersebut adalah numpy-<version_number>-cp37-cp37m-manylinux1_x86_64.whl. Untuk informasi lebih lanjut tentang cara mengunggah paket, lihat Operasi resource atau Contoh UDF: Gunakan paket pihak ketiga dalam UDF Python.

Signature fungsi dan tipe data

Signature fungsi memiliki format berikut.
@annotate(<signature>)
signature adalah string yang mengidentifikasi tipe data parameter input dan nilai kembali. Saat Anda menjalankan UDAF, tipe data parameter input dan nilai kembalinya harus sesuai dengan tipe yang ditentukan dalam signature fungsi. Selama fase parsing kueri, sistem memvalidasi pemanggilan fungsi terhadap signature fungsi. Jika ditemukan ketidaksesuaian tipe, error akan dilaporkan. Format spesifiknya adalah sebagai berikut.
'arg_type_list -> type'
di mana:
  • arg_type_list: Mewakili tipe data parameter input. Beberapa parameter input dapat ditentukan, dipisahkan oleh koma (,). Tipe data yang didukung adalah BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), CHAR, VARCHAR, tipe data kompleks (ARRAY, MAP, STRUCT), dan tipe data kompleks bersarang.

    arg_type_list juga mendukung tanda bintang (*) atau string kosong ('').

    • Jika arg_type_list adalah tanda bintang (*), artinya fungsi menerima sejumlah parameter input apa pun.

    • Jika arg_type_list adalah string kosong (''), artinya fungsi tidak memiliki parameter input.

    Untuk informasi lebih lanjut tentang sintaksis tambahan anotasi Resolve, lihat Parameter dinamis untuk UDAF dan UDTF.

  • type: Mewakili tipe data nilai kembali. UDAF hanya mengembalikan satu kolom. Tipe data yang didukung meliputi BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), tipe data kompleks (ARRAY, MAP, STRUCT), dan tipe data kompleks bersarang.

Catatan Saat menulis kode UDAF, pilih tipe data yang sesuai berdasarkan edisi tipe data proyek MaxCompute Anda. Untuk informasi lebih lanjut tentang edisi tipe data dan tipe data yang didukung oleh setiap edisi, lihat Edisi tipe data.

Berikut adalah contoh signature fungsi yang valid.

Contoh signature fungsiDeskripsi
@annotate('bigint,double->string')Tipe parameter input adalah BIGINT dan DOUBLE, dan tipe nilai kembali adalah STRING.
@annotate('*->string')Fungsi menerima sejumlah parameter input apa pun, dan tipe nilai kembali adalah STRING.
@annotate('->double')Fungsi tidak memiliki parameter input, dan tipe nilai kembali adalah DOUBLE.
@annotate('array<bigint>->struct<x:string, y:int>')Tipe parameter input adalah ARRAY<BIGINT>, dan tipe nilai kembali adalah STRUCT<x:STRING, y:INT>.

Untuk memastikan tipe data dalam UDAF Python Anda konsisten dengan tipe data yang didukung oleh MaxCompute, Anda harus menggunakan pemetaan tipe data yang benar. Tabel berikut menjelaskan pemetaan tersebut.

Tipe MaxCompute SQL

Tipe Python 3

BIGINT

INT

STRING

UNICODE

DOUBLE

FLOAT

BOOLEAN

BOOL

DATETIME

DATETIME.DATETIME

FLOAT

FLOAT

CHAR

UNICODE

VARCHAR

UNICODE

BINARY

BYTES

DATE

DATETIME.DATE

DECIMAL

DECIMAL.DECIMAL

ARRAY

LIST

MAP

DICT

STRUCT

COLLECTIONS.NAMEDTUPLE

Referensi resource

UDAF Python dapat mereferensi resource file dan tabel menggunakan modul odps.distcache.

  • odps.distcache.get_cache_file(resource_name): Mengembalikan objek mirip file untuk resource file yang ditentukan.
    • resource_name bertipe STRING dan bersesuaian dengan nama resource file yang sudah ada di proyek MaxCompute saat ini. Jika nama resource file tidak valid atau resource tersebut tidak ada, pengecualian akan muncul.
      Catatan Untuk mengakses resource dari UDAF, Anda harus mendeklarasikan resource yang direferensikan saat membuat UDAF. Jika tidak, error akan dilaporkan.
    • Nilai kembalinya adalah objek mirip file. Setelah selesai menggunakan objek ini, panggil metode close untuk melepaskan file resource yang terbuka.
  • odps.distcache.get_cache_table(resource_name): Mengembalikan objek generator untuk resource tabel yang ditentukan.
    • resource_name bertipe STRING dan bersesuaian dengan nama resource tabel yang sudah ada di proyek MaxCompute saat ini. Jika nama resource tabel tidak valid atau resource tersebut tidak ada, pengecualian akan muncul.
    • Nilai kembalinya bertipe GENERATOR. Pemanggil melakukan iterasi terhadap generator untuk mengambil konten tabel. Setiap iterasi mengembalikan satu catatan dari tabel sebagai array.

Untuk informasi lebih lanjut tentang penggunaannya, lihat Referensi resource (UDF Python 3) dan Referensi resource (UDTF Python 3).

Catatan penggunaan

Setelah Anda mengembangkan UDAF Python 3 mengikuti alur pengembangan, Anda dapat memanggilnya dalam pernyataan SQL MaxCompute. Metode pemanggilannya adalah sebagai berikut:

  • Gunakan UDF dalam proyek MaxCompute: Metodenya mirip dengan penggunaan fungsi bawaan. Anda dapat menggunakan fungsi yang didefinisikan pengguna dengan cara yang sama seperti menggunakan fungsi bawaan.

  • Gunakan UDF lintas proyek: Gunakan UDF dari Proyek B di Proyek A. Pernyataan berikut menunjukkan contohnya: select B:udf_in_other_project(arg0, arg1) as res from table_t;. Untuk informasi lebih lanjut tentang berbagi lintas proyek, lihat Akses resource lintas proyek berbasis paket.

Untuk prosedur lengkap pengembangan dan pemanggilan UDAF Python 3 menggunakan MaxCompute Studio, lihat Kembangkan UDF Python.

Parameter dinamis untuk UDAF

Signature fungsi

Untuk informasi lebih lanjut tentang format signature fungsi UDAF Python, lihat Signature fungsi dan tipe data.

  • Anda dapat menggunakan tanda bintang (*) dalam daftar parameter untuk menerima parameter input dalam jumlah dan tipe apa pun. Misalnya, @annotate('double,*->string') menunjukkan bahwa parameter pertama bertipe DOUBLE, diikuti oleh daftar parameter dalam jumlah dan tipe apa pun. Dalam hal ini, Anda harus menulis kode untuk menentukan jumlah dan tipe parameter input, lalu melakukan operasi yang sesuai terhadapnya. Ini mirip dengan fungsi printf dalam bahasa C.

    Catatan

    Tanda bintang (*) memiliki makna berbeda saat digunakan dalam daftar nilai kembali.

  • Anda dapat menggunakan tanda bintang (*) dalam nilai kembali UDTF untuk menunjukkan sejumlah nilai kembali bertipe STRING. Jumlah nilai kembali bergantung pada jumlah alias yang ditetapkan saat fungsi dipanggil. Misalnya, untuk @annotate("bigint,string->double,*"), metode pemanggilannya adalah UDTF(x, y) as (a, b, c). Dalam contoh ini, tiga alias ditetapkan setelah as: a, b, dan c. Editor menganggap a bertipe DOUBLE karena tipe kolom pertama dalam nilai kembali ditentukan dalam anotasi, dan menganggap b dan c bertipe STRING. Karena tiga nilai kembali ditentukan, saat UDTF memanggil forward, forward harus berupa array dengan panjang 3. Jika tidak, error waktu proses akan terjadi.

    Catatan

    Jenis error ini tidak dapat dilaporkan pada waktu kompilasi. Oleh karena itu, saat pemanggil UDTF menetapkan jumlah alias dalam pernyataan SQL, mereka harus mengikuti aturan yang ditentukan oleh UDTF. Karena jumlah nilai kembali untuk fungsi agregat tetap 1, fitur ini tidak berlaku untuk UDAF.

Contoh UDAF

from odps.udf import annotate
from odps.udf import BaseUDAF
@annotate('bigint,*->string')
class MultiColSum(BaseUDAF):
    def new_buffer(self):
        return [0]
    def iterate(self, buffer, *args):
        for arg in args:
            buffer[0] += int(arg)
    def merge(self, buffer, pbuffer):
        buffer[0] += pbuffer[0]
    def terminate(self, buffer):
        return str(buffer[0])

UDAF hanya dapat memiliki satu nilai kembali. Dalam contoh UDAF di atas, nilai kembalinya adalah jumlah dari beberapa parameter input, yang kemudian diagregasi dan dijumlahkan di beberapa baris. Kode berikut memberikan contoh penggunaannya.

-- Menjumlahkan beberapa parameter input.
SELECT my_multi_col_sum(a,b,c,d,e) from values (1,"2","3","4","5"), (6,"7","8","9","10") t(a,b,c,d,e);
-- Nilai kembalinya adalah 55.