MaxCompute, Python 2.7 sürümünü kullanır. Bu konuda, Python 2 ile kullanıcı tanımlı bir toplama işlevi (UDAF) nasıl yazılacağı açıklanmaktadır.
UDAF kod yapısı
Python 2 ile UDAF yazmak için
kullanabilirsiniz. Kod aşağıdaki bileşenleri içermelidir:
-
Kodlama bildirimi: İsteğe bağlı.
Bildirim biçimi
#coding:utf-8veya# -*- coding: utf-8 -*-şeklindedir. İki biçim de eşdeğerdir. Python 2 kodunuz Çince karakterler içeriyorsa program çalıştırıldığında hata oluşur. Kodun başına bir kodlama bildirimi ekleyin. -
Modülleri içe aktarma: Zorunlu.
En azından
from odps.udf import annotatevefrom odps.udf import BaseUDAFifadelerini içe aktarmanız gerekir.from odps.udf import annotateifadesi, işlev imzası modülünü içe aktararak MaxCompute'ün kodda tanımlanan işlev imzasını tanımasını sağlar.from odps.udf import BaseUDAFifadesi ise Python UDAF'leri için temel sınıfı içe aktarır. Türetilmiş sınıftaiterate,mergeveterminategibi yöntemleri uygulamanız gerekir.UDAF kodunun dosya veya tablo kaynaklarına başvurması gerekiyorsa dosya kaynakları için
from odps.distcache import get_cache_fileveya tablo kaynakları içinfrom odps.distcache import get_cache_tableifadelerini ekleyin. -
İşlev imzası: Zorunlu.
Biçimi
@annotate(<signature>)şeklindedir.signaturegirdi parametrelerinin ve dönüş değerinin veri türlerini tanımlar. İşlev imzaları hakkında daha fazla bilgi için bkz. İşlev imzası ve veri türleri. -
Özel Python sınıfı (türetilmiş sınıf): Zorunlu.
Bu, UDAF kodunun ana yapısıdır. İş mantığınızı uygulayan değişkenleri ve yöntemleri tanımlar. Kodunuzda yerleşik üçüncü taraf kitaplıklara veya dosya ve tablo gibi kaynaklara da başvurabilirsiniz. Daha fazla bilgi için bkz. Üçüncü taraf kitaplıklar veya Kaynaklara başvurma.
-
Python sınıf yöntemlerini uygulama: Zorunlu.
Python sınıfı uygulaması aşağıdaki yöntemleri içerir. Yöntemleri ihtiyacınıza göre uygulayabilirsiniz.
Yöntem tanımı Açıklama BaseUDAF.new_buffer()Toplama işlevinin ara değeri için bir arabellek döndürür. bufferLIST veya DICT gibi bir Marshal nesnesi olmalıdır.bufferboyutu veri hacmiyle birlikte artmamalıdır. Aşırı durumlarda, nesne serileştirmesinden sonrakibufferboyutu 2 MB'yi aşmamalıdır.BaseUDAF.iterate(buffer[, args, ...])argsdeğerlerini ara değerbufferiçinde toplar.BaseUDAF.merge(buffer, pbuffer)Ara değerler buffervepbufferöğelerini birleştirir ve sonucubufferiçinde saklar.BaseUDAF.terminate(buffer)bufferdeğerini MaxCompute SQL'in ilkel veri türüne dönüştürür.
Aşağıdaki kod bir UDAF örneği sunar.
#coding:utf-8
# Import the function signature module and the base class.
from odps.udf import annotate
from odps.udf import BaseUDAF
# Function signature.
@annotate('double->double')
# Custom Python class.
class Average(BaseUDAF):
# Implement the methods of the Python class.
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]
Aşağıdaki şekil, ortalama değeri (
avg
) hesaplayan bir MaxCompute UDAF'in uygulama mantığını ve hesaplama akışını gösterir.

Şekildeki
pr
değeri
pbuffer
ile,
r
değeri ise
buffer
ile eşleşir.
Sınırlamalar
MaxCompute Python 2 UDAF'leri Python 2.7 kullanır ve kullanıcı kodunu kısıtlı bir korumalı alan ortamında çalıştırır. Aşağıdaki davranışlar yasaktır:
Yerel dosyalardan veri okuma ve yerel dosyalara veri yazma.
Alt süreçleri başlatma.
İş parçacıklarını başlatma.
Soket iletişimini etkinleştirme.
Diğer sistemleri kullanarak Python 2 UDF'leri çağırma.
Bu sınırlamalar nedeniyle yüklediğiniz kod Python standart kitaplıkları kullanılarak yazılmalıdır. Yukarıdaki işlemlerde Python standart kitaplıklarındaki modüller veya C uzantı modülleri söz konusuysa bu modüller kullanılamaz. Python standart kitaplıklarındaki modüllerle ilgili aşağıdaki hususlara dikkat edin:
Python standart kitaplıklarına dayanan ve uzantı modüllerine bağımlı olmayan tüm modüller kullanılabilir.
-
Aşağıdaki C uzantı modülleri kullanılabilir:
array ve audioop
binascii ve bisect
cmath, _codecs_cn, _codecs_hk, _codecs_iso2022, _codecs_jp, _codecs_kr, _codecs_tw, _collections ve cStringIO
datetime
_functools ve future_builtins
_heapq ve _hashlib
itertools
_json
_locale ve _lsprof
math, _md5 ve _multibytecodec
operator
_random
_sha256, _sha512, _sha, _struct ve strop
time
unicodedata
_weakref
cPickle
UDF kodunu korumalı alan ortamında çalıştırdığınızda standart çıkışa (sys.stdout) veya standart hata çıkışına (
sys.stderr) yazılabilecek maksimum veri boyutu 20 KB'dır. Boyut 20 KB'yi aşarsa fazladan karakterler yoksayılır.
Üçüncü taraf kitaplıklar
NumPy gibi üçüncü taraf kitaplıklar, standart kitaplıklara ek olarak MaxCompute'ün Python 2 ortamına yüklenmiştir.
Üçüncü taraf kitaplıkların kullanımı bazı sınırlamalara tabidir. Örneğin, üçüncü taraf bir kitaplık kullanırken yerel verilere erişmenize izin verilmez ve yalnızca sınırlı ağ G/Ç kaynaklarını kullanabilirsiniz. Üçüncü taraf kitaplıklardaki ilgili API'ler devre dışı bırakılmıştır.
İşlev imzası ve veri türleri
İşlev imzası aşağıdaki biçime sahiptir.
@annotate(<signature>)
signature
, girdi parametrelerinin ve dönüş değerinin veri türlerini belirten bir dizedir. Bir UDAF çalıştırdığınızda girdi parametrelerinin ve dönüş değerinin veri türleri işlev imzasında belirtilen türlerle eşleşmelidir. Sorgu ayrıştırma aşamasında sistem işlev çağrısını işlev imzasına göre doğrular. Tür uyuşmazlığı tespit edilirse hata raporlanır. Belirli biçim aşağıdaki gibidir.
'arg_type_list -> type'
Burada:
-
arg_type_list: Girdi parametrelerinin veri türlerini temsil eder. Birden çok girdi parametresi virgülle (,) ayrılarak belirtilebilir. Desteklenen veri türleri BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), CHAR, VARCHAR, karmaşık veri türleri (ARRAY, MAP, STRUCT) ve iç içe geçmiş karmaşık veri türleridir.arg_type_listayrıca yıldız işareti (*) veya boş dize ('') değerlerini destekler.arg_type_listbir yıldız işareti (*) ise işlevin herhangi bir sayıda girdi parametresini kabul ettiği anlamına gelir.arg_type_listboş bir dize ('') ise işlevin girdi parametresi olmadığı anlamına gelir.
Resolve ek açıklamalarının genişletilmiş sözdizimi hakkında daha fazla bilgi için bkz. UDAF'ler ve UDTF'ler için dinamik parametreler.
type: Dönüş değerinin veri türünü temsil eder. Bir UDAF yalnızca bir sütun döndürür. Desteklenen veri türleri BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), karmaşık veri türleri (ARRAY, MAP, STRUCT) ve iç içe geçmiş karmaşık veri türlerini içerir.
UDAF kodunu yazarken MaxCompute projenizin veri türü sürümüne göre uygun veri türlerini seçin. Veri türü sürümleri ve her sürüm tarafından desteklenen veri türleri hakkında daha fazla bilgi için bkz.
.
Aşağıdakiler geçerli işlev imzalarıdır.
| İşlev imzası örneği | Açıklama |
@annotate('bigint,double->string') |
Girdi parametresi türleri BIGINT ve DOUBLE, dönüş değeri türü STRING'dir. |
@annotate('*->string') |
İşlev herhangi bir sayıda girdi parametresini kabul eder ve dönüş değeri türü STRING'dir. |
@annotate('->double') |
İşlevin girdi parametresi yoktur ve dönüş değeri türü DOUBLE'dır. |
@annotate('array<bigint>->struct<x:string, y:int>') |
Girdi parametresi türü ARRAY |
Python UDAF'inizdeki veri türlerinin MaxCompute tarafından desteklenen veri türleriyle tutarlı olduğundan emin olmak için doğru veri türü eşlemelerini kullanmanız gerekir. Aşağıdaki tabloda bu eşlemeler açıklanmaktadır.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MaxCompute SQL'de desteklenen DATETIME türü, Python veri türü INT ile eşlenir. INT türündeki bir değer, 1 Ocak 1970 Perşembe 00:00:00 tarihinden bu yana geçen milisaniye sayısını ifade eden UNIX biçimini takip eder. DATETIME türündeki verileri Python standart kitaplıklarındaki DATETIME modülünü kullanarak işleyebilirsiniz.
odps.udf.int(value)ifadesinesilentparametresi eklenmiştir.silentparametresi True olarak ayarlanırsa vevaluedeğerinin veri türü INT türüne dönüştürülemezse None döndürülür ve hata döndürülmez.MaxCompute SQL'deki NULL değeri Python 2'de None ile eşlenir.
Kaynaklara başvurma
Python UDAF'leri odps.distcache modülünü kullanarak dosya ve tablo kaynaklarına başvurabilir.
-
odps.distcache.get_cache_file(resource_name): Belirtilen dosya kaynağı için dosya benzeri bir nesne döndürür.-
resource_nameSTRING türündedir ve geçerli MaxCompute projesindeki mevcut bir dosya kaynağının adıyla eşleşir. Dosya kaynağı adı geçersizse veya kaynak yoksa bir özel durum oluşturulur.NotBir UDAF'ten bir kaynağa erişmek için UDAF'i oluştururken başvurulan kaynağı bildirmeniz gerekir. Aksi takdirde hata oluşur.
Dönüş değeri dosya benzeri bir nesnedir. Bu nesneyi kullanmayı bitirdikten sonra açık kaynak dosyasını serbest bırakmak için
closeyöntemini çağırın.
-
-
odps.distcache.get_cache_table(resource_name): Belirtilen tablo kaynağı için bir oluşturucu nesnesi döndürür.resource_nameSTRING türündedir ve geçerli MaxCompute projesindeki mevcut bir tablo kaynağının adıyla eşleşir. Tablo kaynağı adı geçersizse veya kaynak yoksa bir özel durum oluşturulur.Dönüş değeri GENERATOR türündedir. Çağıran, tablo içeriğini almak için oluşturucuyu yineleme yoluyla tarar. Her yinelemede tablodan bir kayıt dizi olarak döndürülür.
Kaynakların nasıl kullanılacağı hakkında daha fazla bilgi için bkz. Kaynaklara başvurma (Python 2 UDF'leri) ve Kaynaklara başvurma (Python 2 UDTF'leri).
Kullanım notları
Python 2 UDAF'i
takip ederek geliştirdikten sonra MaxCompute SQL'de çağırabilirsiniz. UDAF'i aşağıdaki şekillerde çağırabilirsiniz:
Bir MaxCompute projesinde UDF kullanma: Yöntem, yerleşik işlevleri kullanmaya benzer. Kullanıcı tanımlı bir işlevi yerleşik bir işlevle aynı şekilde kullanabilirsiniz.
Projeler arasında UDF kullanma: B Projesindeki bir UDF'i A Projesinde kullanma. Aşağıdaki ifade bir örnek gösterir:
select B:udf_in_other_project(arg0, arg1) as res from table_t;. Projeler arası paylaşım hakkında daha fazla bilgi için bkz. Paketlere dayalı projeler arası kaynak erişimi.
MaxCompute Studio'da Python 2 UDAF'in nasıl geliştirileceği ve çağrılacağı hakkında daha fazla bilgi için bkz. Python UDF geliştirme.