MaxCompute, Python 2 kullanıcı tanımlı tablo değerli işlevlerini (UDTF) Python 2.7 kullanarak çalıştırır. Bir UDTF tek bir girdi satırı alır ve sıfır veya daha fazla çıktı satırı döndürür; bu özellik verileri bölme veya genişletme gibi işlemler için kullanışlıdır.
Bir Python 2 UDTF oluşturmak ve kullanmak için:
Gerekli yöntemleri uygulayan ve
BaseUDTFsınıfından türetilen bir Python sınıfı yazın.Sınıfı MaxCompute'da bir UDTF olarak kaydedin ve ardından MaxCompute SQL içinde çağırın.
UDTF kod yapısı
Bir Python 2 UDTF en fazla beş bileşenden oluşur.
| Bileşen | Zorunlu | Açıklama |
|---|---|---|
| Kodlama bildirimi | Hayır | Dosya kodlamasını bildirir. #coding:utf-8 veya # -*- coding: utf-8 -*- kullanın. Kodda Çince karakterler varsa bu bildirimi ekleyin; aksi takdirde MaxCompute çalışma zamanında hata döndürür. |
| Modül içe aktarmaları | Evet | from odps.udf import annotate ve from odps.udf import BaseUDTF ifadelerini içermelidir. UDTF dosya veya tablo kaynaklarına başvuruyorsa from odps.distcache import get_cache_file veya from odps.distcache import get_cache_table ifadelerini ekleyin. |
| İşlev imzası | Hayır | Giriş ve çıkış veri türlerini bildirmek üzere UDTF'yi @annotate(<signature>) ile açıklar. İmza olmadan MaxCompute herhangi bir giriş türünü kabul eder ancak tüm çıkış değerlerini STRING olarak değerlendirir. |
| Türetilmiş sınıf | Evet | BaseUDTF sınıfından türetilen bir Python sınıfıdır. Bu sınıf tüm UDTF mantığını içerir. |
| Sınıf yöntemleri | Evet | En azından process yöntemini uygulayın. Aşağıdaki yöntemler tablosuna bakın. |
Yöntemler
| Yöntem | Zorunlu | Açıklama |
|---|---|---|
BaseUDTF.init() |
Hayır | İlk kayıt işlenmeden önce durumu başlatır. init yöntemini geçersiz kılıyorsanız başlangıçta super(BaseUDTF, self).init() çağrısını yapın. UDTF'nin kayıtlar arasında sürdürmesi gereken durumu ayarlamak için bu yöntemi kullanın. |
BaseUDTF.process([args, ...]) |
Evet | Her girdi satırı için bir kez çağrılır. Bağımsız değişkenler, SQL'de belirtildiği şekilde UDTF'nin giriş parametreleriyle eşleşir. |
BaseUDTF.forward([args, ...]) |
Evet (process içinde çağrılır) |
Her çağrıldığında bir çıkış satırı yayar. Döndürmek istediğiniz her satır için bu yöntemi bir kez çağırın. İşlev imzası tanımlanmamışsa forward öğesini çağırmadan önce tüm bağımsız değişkenleri STRING'e dönüştürün. |
BaseUDTF.close() |
Hayır | Son kayıt işlenmeden önce bir kez çağrılır. Kaynakları serbest bırakmak veya çıkışı temizlemek için bu yöntemi kullanın. |
Örnek
Aşağıdaki UDTF virgülle ayrılmış bir dizeyi böler ve her değeri ayrı bir satır olarak yayar.
#coding:utf-8
from odps.udf import annotate
from odps.udf import BaseUDTF
@annotate('string -> string')
class Explode(BaseUDTF):
def process(self, arg):
props = arg.split(',')
for p in props:
self.forward(p)
İşlev imzaları ve veri türleri
İmza biçimi
@annotate('arg_type_list -> type_list')
arg_type_list: Giriş parametresi türlerinin virgülle ayrılmış listesi. Herhangi bir sayıda bağımsız değişkeni kabul etmek için*kullanın veya bağımsız değişken kabul etmemek için boş bırakın.type_list: Dönüş değeri türlerinin virgülle ayrılmış listesi. Bir UDTF birden çok sütun döndürebilir.
Aşağıdaki tabloda geçerli imza örnekleri gösterilmektedir.
| İmza | Giriş türleri | Dönüş türleri |
|---|---|---|
@annotate('bigint,boolean->string,datetime') |
BIGINT, BOOLEAN | STRING, DATETIME |
@annotate('*->string,datetime') |
Herhangi bir sayıda bağımsız değişken | STRING, DATETIME |
@annotate('->double,bigint,string') |
Yok | DOUBLE, BIGINT, STRING |
@annotate("array<string>,struct<a1:bigint,b1:string>,string->map<string,bigint>,struct<b1:bigint>") |
ARRAY, STRUCT, STRING | MAP, STRUCT |
Anlamsal ayrıştırma sırasında MaxCompute gerçek bağımsız değişkenlerin veri türlerinin imzayla eşleşip eşleşmediğini denetler. Eşleşmeme durumunda hata döndürülür.
Kullanılabilir veri türleri MaxCompute projenizin veri türü sürümüne bağlıdır. Daha fazla bilgi için bkz. Veri türü sürümleri.
Veri türü eşlemeleri
UDTF kodunu MaxCompute SQL türlerine karşılık gelen Python türlerini kullanarak yazın.
| MaxCompute SQL türü | Python 2 türü |
|---|---|
| BIGINT | int |
| STRING | str |
| DOUBLE | float |
| BOOLEAN | bool |
| DATETIME | int (1 Ocak 1970, 00:00:00 UTC'den bu yana geçen milisaniye) |
| FLOAT | float |
| CHAR | str |
| VARCHAR | str |
| BINARY | bytearray |
| DATE | int |
| DECIMAL | decimal.Decimal |
| ARRAY | list |
| MAP | dict |
| STRUCT | collections.namedtuple |
Tür işlemeye ilişkin ek notlar:
MaxCompute SQL'deki NULL, Python'da
Nonedeğerine eşlenir.odps.udf.int(value, silent=True)ifadesi değer int'e dönüştürülemediğinde hata vermek yerineNonedöndürür.
Dosya ve tablo kaynaklarına başvuru
Dosya veya tablo kaynaklarını UDTF'nize yüklemek için odps.distcache modülünü kullanın.
get_cache_file(resource_name): Adlandırılmış dosya kaynağı için dosya benzeri bir nesne döndürür. İşiniz bittiğinde nesne üzerindeclose()çağrısını yapın. UDTF'yi kaydederken dosya kaynağını bildirin; aksi takdirde çağrı çalışma zamanında başarısız olur.get_cache_table(resource_name): Adlandırılmış tablo kaynağı üzerinden bir üreteç döndürür. Her yineleme bir kaydı liste (ARRAY türü) olarak verir.
Aşağıdaki örnekte bir JSON dosyası ve bir tablo kaynağı yüklenir ve ardından sayfa kimliğine göre reklam kimliklerini aramak için kullanılır.
# -*- 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):
def __init__(self):
import json
# Load the JSON file resource into a dict
cache_file = get_cache_file('test_json.txt')
self.my_dict = json.load(cache_file)
cache_file.close()
# Merge records from the table resource
records = list(get_cache_table('table_resource1'))
for record in records:
self.my_dict[record[0]] = [record[1]]
def process(self, pageid):
# Emit one row per ad ID associated with the page
for adid in self.my_dict[pageid]:
self.forward(pageid, adid)
UDTF'yi MaxCompute SQL içinde çağırma
Geliştirme sürecini tamamladıktan sonra UDTF'yi MaxCompute SQL'den çağırın:
Proje içinde: UDTF'yi yerleşik işlevleri çağırdığınız şekilde çağırın.
-
Projeler arasında: B projesindeki bir UDTF'yi A projesinde kullanmak için işlev adının önüne proje adını ekleyin:
SELECT B:udf_in_other_project(arg0, arg1) AS res FROM table_t;Daha fazla bilgi için bkz. Paketlere dayalı proje arası kaynak erişimi.
Sınırlamalar
MaxCompute Python 2 UDTF kodunu bir korumalı alan ortamında çalıştırır. Aşağıdaki işlemlere izin verilmez:
Yerel dosyalardan okuma veya yerel dosyalara yazma
Alt süreçleri başlatma
İş parçacıklarını başlatma
Soket bağlantıları açma
Diğer sistemlerden Python 2 UDF'leri çağırma
Yalnızca Python standart kitaplıklarını kullanan kodu yükleyin. Yukarıda belirtilen kısıtlı işlemlere bağlı olan modüller veya C uzantı modülleri kullanılamaz.
Kullanılabilir C uzantı modülleri
Korumalı alanda aşağıdaki C uzantı modülleri kullanılabilir:
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, _random, _sha256, _sha512, _sha, _struct, strop, time, unicodedata, _weakref, cPickle
Uzantı modüllerine bağlı olmayan ve tamamen Python'da uygulanmış tüm modüller de kullanılabilir.
Çıkış boyutu sınırı
sys.stdout veya sys.stderr konumuna yazma işlemi 20 KB ile sınırlıdır. Bu sınırın üzerindeki karakterler sessizce atılır.
Üçüncü taraf kitaplıklar
NumPy gibi üçüncü taraf kitaplıklar MaxCompute Python 2 ortamında önceden yüklüdür. Yerel veri erişimi ve çoğu ağ G/Ç API'si üçüncü taraf kitaplıklar için devre dışı bırakılmıştır; yalnızca sınırlı ağ G/Ç kullanılabilir.