Todos os produtos
Search
Central de documentação

MaxCompute:UDAF em Python 2

Última atualização: Aug 21, 2026

O MaxCompute usa o Python 2.7. Este tópico descreve como escrever uma função de agregação definida pelo usuário (UDAF) em Python 2.

Estrutura do código da UDAF

Use o

MaxCompute Studio

para desenvolver uma UDAF em Python 2. O código deve incluir os seguintes componentes:

  • Declaração de codificação: opcional.

    O formato da declaração é #coding:utf-8 ou # -*- coding: utf-8 -*-. Ambos os formatos são equivalentes. Se o código Python 2 contiver caracteres chineses, ocorrerá um erro durante a execução. Adicione uma declaração de codificação no início do código para evitar esse problema.

  • Importação de módulos: obrigatória.

    Importe pelo menos from odps.udf import annotate e from odps.udf import BaseUDAF. A instrução from odps.udf import annotate importa o módulo de assinatura da função e permite que o MaxCompute reconheça a assinatura definida no código. A instrução from odps.udf import BaseUDAF importa a classe base para UDAFs em Python. Implemente métodos como iterate, merge e terminate na classe derivada.

    Se o código da UDAF precisar referenciar recursos de arquivo ou tabela, inclua from odps.distcache import get_cache_file para recursos de arquivo ou from odps.distcache import get_cache_table para recursos de tabela.

  • Assinatura da função: obrigatória.

    O formato é @annotate(<signature>). O parâmetro signature define os tipos de dados dos parâmetros de entrada e do valor de retorno. Para obter mais informações sobre assinaturas de função, consulte Function signature and data types.

  • Classe Python personalizada (classe derivada): obrigatória.

    Esta é a estrutura principal do código da UDAF. Ela define as variáveis e os métodos que implementam a lógica de negócios. Também é possível referenciar bibliotecas de terceiros integradas ou recursos, como arquivos e tabelas, diretamente no código. Para obter mais detalhes, consulte Third-party libraries ou Referencing resources.

  • Implementação dos métodos da classe Python: obrigatória.

    A implementação da classe Python inclui os métodos listados abaixo. Implemente-os conforme a necessidade.

    Definição do método

    Descrição

    BaseUDAF.new_buffer()

    Retorna um buffer para o valor intermediário da função de agregação. O buffer deve ser um objeto Marshal, como LIST ou DICT. O tamanho do buffer não deve aumentar proporcionalmente ao volume de dados. Em casos extremos, o tamanho do buffer após a serialização do objeto não pode exceder 2 MB.

    BaseUDAF.iterate(buffer[, args, ...])

    Agrega os argumentos args ao valor intermediário armazenado em buffer.

    BaseUDAF.merge(buffer, pbuffer)

    Combina os valores intermediários buffer e pbuffer e armazena o resultado em buffer.

    BaseUDAF.terminate(buffer)

    Converte o conteúdo do buffer em um tipo de dados primitivo do MaxCompute SQL.

O exemplo a seguir ilustra o código de uma UDAF.

#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 figura a seguir apresenta a lógica de implementação e o fluxo de cálculo de uma UDAF do MaxCompute usada para calcular a média (

avg

).

求平均值逻辑

O termo

pbuffer

corresponde a

pr

na figura, enquanto

buffer

corresponde a

r

.

Limitações

As UDAFs em Python 2 do MaxCompute usam o Python 2.7 e executam o código do usuário em um ambiente sandbox restrito. As seguintes ações são proibidas:

  • Ler e gravar dados em arquivos locais.

  • Iniciar subprocessos.

  • Iniciar threads.

  • Estabelecer comunicação via socket.

  • Chamar UDFs Python 2 por outros sistemas.

Devido a essas limitações, o código enviado deve usar exclusivamente bibliotecas padrão do Python. Módulos ou extensões em C que realizem as operações proibidas acima não podem ser usados. Observe os pontos seguintes sobre os módulos das bibliotecas padrão:

  • Todos os módulos implementados com base nas bibliotecas padrão do Python, sem dependência de módulos de extensão, estão disponíveis.

  • Os seguintes módulos de extensão em C estão disponíveis:

    • array e audioop

    • binascii e bisect

    • cmath, _codecs_cn, _codecs_hk, _codecs_iso2022, _codecs_jp, _codecs_kr, _codecs_tw, _collections e cStringIO

    • datetime

    • _functools e future_builtins

    • _heapq e _hashlib

    • itertools

    • _json

    • _locale e _lsprof

    • math, _md5 e _multibytecodec

    • operator

    • _random

    • _sha256, _sha512, _sha, _struct e strop

    • time

    • unicodedata

    • _weakref

    • cPickle

  • Ao executar o código da UDF no ambiente sandbox, o tamanho máximo dos dados gravados na saída padrão (sys.stdout) ou na saída de erro padrão (sys.stderr) é de 20 KB. Qualquer conteúdo que exceda esse limite será ignorado.

Bibliotecas de terceiros

Bibliotecas de terceiros, como NumPy, já vêm instaladas no ambiente Python 2 do MaxCompute para complementar as bibliotecas padrão.

Nota

O uso de bibliotecas de terceiros está sujeito a certas limitações. Por exemplo, ao usar essas bibliotecas, não é permitido acessar dados locais, e os recursos de I/O de rede são restritos. As APIs relacionadas nessas bibliotecas ficam desativadas.

Assinatura da função e tipos de dados

A assinatura da função segue o formato abaixo.

@annotate(<signature>)

O parâmetro

signature

é uma string que identifica os tipos de dados dos parâmetros de entrada e do valor de retorno. Ao executar uma UDAF, os tipos de dados de entrada e saída devem corresponder exatamente aos especificados na assinatura. Durante a fase de análise da consulta, o sistema valida a chamada da função contra essa assinatura e reporta um erro caso haja incompatibilidade de tipos. O formato específico é:

'arg_type_list -> type'

onde:

  • arg_type_list: representa os tipos de dados dos parâmetros de entrada. É possível especificar múltiplos parâmetros separados por vírgula (,). Os tipos suportados incluem BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), CHAR, VARCHAR, tipos complexos (ARRAY, MAP, STRUCT) e tipos complexos aninhados.

    O campo arg_type_list também aceita um asterisco (*) ou uma string vazia ('').

    • Quando arg_type_list for um asterisco (*), indica que a função aceita qualquer quantidade de parâmetros de entrada.

    • Quando arg_type_list for uma string vazia (''), indica que a função não possui parâmetros de entrada.

    Para obter mais detalhes sobre a sintaxe estendida da anotação Resolve, consulte Dynamic parameters for UDAFs and UDTFs.

  • type: define o tipo de dado do valor de retorno. Uma UDAF retorna apenas uma coluna. Os tipos suportados são BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), tipos complexos (ARRAY, MAP, STRUCT) e tipos complexos aninhados.

Nota

Ao escrever o código da UDAF, escolha os tipos de dados adequados à edição de tipos de dados do seu projeto MaxCompute. Para saber mais sobre as edições e os tipos suportados em cada uma, consulte

Data type editions

.

Veja a seguir exemplos válidos de assinaturas de função.

Exemplo de assinatura

Descrição

@annotate('bigint,double->string')

Os parâmetros de entrada são BIGINT e DOUBLE; o retorno é STRING.

@annotate('*->string')

Aceita número variável de parâmetros de entrada; o retorno é STRING.

@annotate('->double')

Não há parâmetros de entrada; o retorno é DOUBLE.

@annotate('array<bigint>->struct<x:string, y:int>')

Entrada do tipo ARRAY; retorno do tipo STRUCT.

Para garantir a consistência entre os tipos de dados da sua UDAF Python e os tipos suportados pelo MaxCompute, use os mapeamentos corretos descritos na tabela a seguir.

Tipo de dado MaxCompute SQL

Tipo de dado 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

Nota
  • O tipo DATETIME do MaxCompute SQL é mapeado para INT em Python. O valor INT segue o padrão UNIX, representando o número de milissegundos decorridos desde 00:00:00 de quinta-feira, 1º de janeiro de 1970. Use o módulo DATETIME das bibliotecas padrão do Python para processar esses dados.

  • O parâmetro silent foi adicionado à função odps.udf.int(value). Se o parâmetro silent estiver definido como True e o tipo de dado de value não puder ser convertido para INT, a função retornará None sem gerar erro.

  • Valores NULL no MaxCompute SQL correspondem a None em Python 2.

Referência a recursos

UDAFs em Python podem referenciar recursos de arquivo e tabela por meio do módulo odps.distcache.

  • odps.distcache.get_cache_file(resource_name): retorna um objeto semelhante a arquivo para o recurso de arquivo especificado.

    • O parâmetro resource_name é do tipo STRING e corresponde ao nome de um recurso de arquivo existente no projeto MaxCompute atual. Se o nome for inválido ou o recurso não existir, uma exceção será lançada.

      Nota

      Para acessar um recurso a partir de uma UDAF, declare-o explicitamente durante a criação da função. Caso contrário, ocorrerá um erro.

    • O valor retornado é um objeto semelhante a arquivo. Após concluir o uso, chame o método close para liberar o arquivo de recurso aberto.

  • odps.distcache.get_cache_table(resource_name): retorna um objeto gerador para o recurso de tabela especificado.

    • O parâmetro resource_name é do tipo STRING e corresponde ao nome de um recurso de tabela existente no projeto MaxCompute atual. Nomes inválidos ou recursos inexistentes resultam em exceção.

    • O retorno é do tipo GENERATOR. O chamador percorre o gerador para obter o conteúdo da tabela e recebe um registro por iteração na forma de array.

Para obter mais informações sobre o uso de recursos, consulte Reference resources (Python 2 UDFs) e Reference resources (Python 2 UDTFs).

Observações de uso

Após desenvolver uma UDAF em Python 2 seguindo as orientações de

development flow

, chame-a diretamente no MaxCompute SQL. Existem duas formas principais de invocação:

  • Uso dentro do mesmo projeto MaxCompute: o procedimento é semelhante ao descrito em built-in functions. Use a função definida pelo usuário da mesma forma que uma função nativa.

  • Uso entre projetos diferentes: permite chamar uma UDF do Projeto B estando no Projeto A. Exemplo de comando: select B:udf_in_other_project(arg0, arg1) as res from table_t;. Para obter detalhes sobre compartilhamento entre projetos, consulte Cross-project resource access based on packages.

Para obter instruções completas sobre desenvolvimento e chamada de UDAFs Python 2 no MaxCompute Studio, consulte Develop a Python UDF.