Todos os produtos
Search
Central de documentação

MaxCompute:Desenvolver uma UDF em Python 3

Última atualização: Jun 26, 2026

O MaxCompute oferece suporte a funções definidas pelo usuário (UDFs) escritas em Python 3, o que permite estender o SQL com lógica de negócios personalizada. Ao chamar uma UDF, o MaxCompute passa o nome da função e os argumentos para o runtime do Python. O runtime executa o método evaluate e retorna o resultado à consulta.

Início rápido

O exemplo mínimo a seguir soma dois inteiros e trata entradas NULL:

from odps.udf import annotate

@annotate("bigint,bigint->bigint")
class MyPlus(object):
    def evaluate(self, arg0, arg1):
        if None in (arg0, arg1):
            return None
        return arg0 + arg1

Para executar uma UDF em Python 3, adicione o seguinte sinalizador de sessão antes da instrução SQL:

SET odps.sql.python.version=cp37;
SELECT my_plus(col_a, col_b) FROM my_table;

Estrutura do código da UDF

Toda UDF em Python 3 exige quatro componentes:

Componente

Descrição

Importação de módulo

from odps.udf import annotate importa o decorador @annotate, usado para declarar a assinatura da função. Para referenciar arquivos ou tabelas no código da UDF, importe também from odps.distcache import get_cache_file ou from odps.distcache import get_cache_table.

Assinatura da função

@annotate(<signature>) declara os tipos de entrada e de retorno. O MaxCompute valida a consistência dos tipos durante a análise semântica e retorna um erro se houver incompatibilidade. Consulte Assinaturas de função e tipos de dados.

Classe Python personalizada

A classe é a unidade organizacional da UDF. Ela define as variáveis e os métodos que implementam a lógica de negócios. As classes também podem referenciar bibliotecas de terceiros pré-instaladas no MaxCompute, além de arquivos e tabelas externos. Consulte Bibliotecas de terceiros e Referenciar recursos.

Método evaluate

Definido na classe, o método evaluate especifica os parâmetros de entrada e o valor de retorno da UDF. Cada classe pode ter apenas um método evaluate.

Limitações

Acesso à internet (aplicado em tempo de execução)

Por padrão, as UDFs não têm acesso à internet. Para ativar esse acesso, envie um Formulário de Solicitação de Conexão de Rede. A equipe de suporte técnico do MaxCompute entrará em contato para concluir a configuração. Para obter instruções, consulte Formulário de Solicitação de Conexão de RedeProcesso de Acesso à Rede.

Acesso à VPC (aplicado em tempo de execução)

Por padrão, as UDFs não acessam nuvens privadas virtuais (VPCs). Para acessar recursos da VPC a partir de uma UDF, crie primeiro uma conexão de rede entre o projeto do MaxCompute e a VPC de destino. Para mais informações, consulte Acessar recursos em uma VPC usando uma UDF.

Leitura de dados de tabela (aplicado em tempo de execução)

UDFs, funções de agregação definidas pelo usuário (UDAFs) e funções com valor de tabela definidas pelo usuário (UDTFs) não podem ler dados dos seguintes tipos de tabela:

  • Tabelas com esquemas modificados (Evolução de Esquema)

  • Tabelas com tipos de dados complexos

  • Tabelas com o tipo de dados JSON

  • Tabelas transacionais

Notas de uso

Python 2 e Python 3 não são compatíveis. Não misture UDFs em Python 2 e Python 3 na mesma instrução SQL.

O Python 2 atingiu o fim da vida útil (EOL) no início de 2020. Para obter orientações sobre como migrar UDFs existentes, consulte Migrar UDFs em Python 2.

Tratamento de NULL

Trate valores NULL explicitamente no método evaluate:

def evaluate(self, arg):
    if arg is None:
        return None
    return arg.upper()

Desenvolver uma UDF

O MaxCompute permite desenvolver UDFs com o MaxCompute Studio, o DataWorks e o cliente do MaxCompute (odpscmd). Todas as três ferramentas seguem o mesmo fluxo de trabalho:

  1. Escreva o código da UDF

  2. Faça upload do arquivo Python e registre a função

  3. Chame a UDF no SQL

As seções a seguir detalham o fluxo de trabalho para cada ferramenta, utilizando a mesma função de exemplo GetUrlChar, que extrai um segmento de URL por posição.

Usar o MaxCompute Studio

Pré-requisitos

Antes de começar, certifique-se de ter:

Escrever o código da UDF

  1. No painel Project, clique com o botão direito em scripts sob o MaxCompute script module e escolha New > MaxCompute Python.

  2. Na caixa de diálogo Create new MaxCompute python class, insira um nome de classe em Name, selecione python UDF na lista suspensa Kind e clique em OK.

  3. Escreva o código da UDF no editor. Exemplo:

    Para testes locais de UDF, consulte Testar UDFs .
    from odps.udf import annotate
    
    @annotate("string,bigint->string")
    class GetUrlChar(object):
    
        def evaluate(self, url, n):
            if n == 0:
                return ""
            try:
                index = url.find(".htm")
                if index < 0:
                    return ""
                a = url[:index]
                index = a.rfind("/")
                b = a[index + 1:]
                c = b.split("-")
                if len(c) < n:
                    return ""
                return c[-n]
            except Exception:
                return "Internal error"

Fazer upload do arquivo e registrar a função

Clique com o botão direito no arquivo Python na pasta scripts e selecione Deploy to server.... Na caixa de diálogo Submit resource and register function, insira o nome da função e clique em OK. Para detalhes, consulte Fazer upload de um programa Python e criar uma UDF do MaxCompute.

Chamar a UDF

Na aba Project Explore, clique com o botão direito no projeto do MaxCompute, selecione Open Console e execute:

SET odps.sql.python.version=cp37;
SELECT UDF_GET_URL_CHAR("http://www.taobao.com/a.htm", 1);

Resultado:

+-----+
| _c0 |
+-----+
|  a  |
+-----+

Usar o DataWorks

Pré-requisitos

Antes de começar, certifique-se de ter ativado o DataWorks e associado um workspace do DataWorks ao projeto do MaxCompute. Para instruções de configuração, consulte DataWorks.

Escrever o código da UDF

Escreva o código da UDF em qualquer editor Python. Exemplo:

from odps.udf import annotate

@annotate("string,bigint->string")
class GetUrlChar(object):

    def evaluate(self, url, n):
        if n == 0:
            return ""
        try:
            index = url.find(".htm")
            if index < 0:
                return ""
            a = url[:index]
            index = a.rfind("/")
            b = a[index + 1:]
            c = b.split("-")
            if len(c) < n:
                return ""
            return c[-n]
        except Exception:
            return "Internal error"

Fazer upload do arquivo e registrar a função

Faça upload do código empacotado no console do DataWorks e crie a UDF. Consulte:

Chamar a UDF

Crie um nó ODPS SQL no console do DataWorks e execute:

SET odps.sql.python.version=cp37;
SELECT UDF_GET_URL_CHAR("http://www.taobao.com/a.htm", 1);

Para mais informações sobre nós ODPS SQL, consulte Desenvolver uma tarefa SQL do MaxCompute.

Usar o cliente do MaxCompute (odpscmd)

Pré-requisitos

Antes de começar, certifique-se de ter baixado, instalado e configurado o cliente do MaxCompute (odpscmd). Para instruções de configuração, consulte Cliente do MaxCompute (odpscmd).

Escrever o código da UDF

Escreva o código da UDF em qualquer editor Python. Exemplo:

from odps.udf import annotate

@annotate("string,bigint->string")
class GetUrlChar(object):

    def evaluate(self, url, n):
        if n == 0:
            return ""
        try:
            index = url.find(".htm")
            if index < 0:
                return ""
            a = url[:index]
            index = a.rfind("/")
            b = a[index + 1:]
            c = b.split("-")
            if len(c) < n:
                return ""
            return c[-n]
        except Exception:
            return "Internal error"

Fazer upload do arquivo e registrar a função

Faça upload do arquivo Python e registre a UDF usando os seguintes comandos:

Chamar a UDF

Execute o seguinte SQL no cliente:

SET odps.sql.python.version=cp37;
SELECT UDF_GET_URL_CHAR("http://www.taobao.com/a.htm", 1);

Bibliotecas de terceiros

O runtime Python 3 integrado ao MaxCompute não inclui o NumPy. Para usar o NumPy, faça upload manual do pacote wheel do NumPy. Baixe o pacote do PyPI ou de um espelho. O nome do arquivo segue o padrão numpy-<version>-cp37-cp37m-manylinux1_x86_64.whl.

Para instruções de upload, consulte Operações de recursos ou Usar pacotes de terceiros em UDFs Python.

Para obter a lista completa das bibliotecas padrão disponíveis no runtime Python 3,7, consulte A Biblioteca Padrão do Python.

Assinaturas de função e tipos de dados

Antes de escrever o código da UDF, defina:

  • Quais tipos de entrada a função aceita e qual tipo ela retorna

  • Como a função trata entradas NULL (o MaxCompute pode passar NULLs para qualquer UDF)

A assinatura da função usa o decorador @annotate:

@annotate(<signature>)

O formato da string de assinatura é:

'arg_type_list -> type'

Tipos de entrada (arg_type_list)

Separe vários tipos de entrada com vírgulas. Os seguintes tipos têm suporte:

BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), CHAR, VARCHAR e tipos complexos ARRAY, MAP, STRUCT (incluindo tipos complexos aninhados).

Dois valores especiais para arg_type_list:

Valor

Significado

*

Aceita qualquer número de argumentos

'' (string vazia)

Não aceita argumentos

Tipo de retorno (type)

As UDFs retornam uma única coluna. Os tipos de retorno com suporte são:

BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale) e tipos complexos ARRAY, MAP, STRUCT (incluindo tipos complexos aninhados).

Os tipos disponíveis dependem da edição de tipos de dados do MaxCompute usada pelo projeto. Para detalhes, consulte Edições de tipos de dados .

Exemplos de assinatura

Assinatura

Descrição

'bigint,double->string'

Recebe entradas BIGINT e DOUBLE, retorna STRING

'*->string'

Recebe qualquer número de entradas, retorna STRING

'->double'

Não recebe entradas, retorna DOUBLE

'array<bigint>->struct<x:string, y:int>'

Recebe ARRAY\, retorna STRUCT\

'->map<bigint, string>'

Não recebe entradas, retorna MAP\

Mapeamentos de tipos do MaxCompute SQL para Python 3

Escreva o código da UDF usando estes mapeamentos de tipos para garantir consistência:

Tipo MaxCompute SQL

Tipo 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

Referenciar recursos

Referencie arquivos ou tabelas no código da UDF usando o módulo odps.distcache.

Referenciar um arquivo

odps.distcache.get_cache_file(resource_name, mode) retorna o conteúdo de um recurso de arquivo.

Parâmetro

Descrição

resource_name

Nome de um recurso de arquivo existente no projeto do MaxCompute. Retorna um erro se o nome for inválido ou se o recurso não existir.

mode

Modo de abertura. 't' (padrão) para texto, 'b' para binário.

O valor de retorno é um objeto semelhante a um arquivo. Chame close() nele ao terminar para liberar o identificador de arquivo.

from odps.udf import annotate
from odps.distcache import get_cache_file

@annotate('bigint->string')
class DistCacheExample(object):
    def __init__(self):
        cache_file = get_cache_file('test_distcache.txt')
        kv = {}
        for line in cache_file:
            line = line.strip()
            if not line:
                continue
            k, v = line.split()
            kv[int(k)] = v
        cache_file.close()
        self.kv = kv

    def evaluate(self, arg):
        return self.kv.get(arg)

Referenciar uma tabela

odps.distcache.get_cache_table(resource_name) retorna o conteúdo de um recurso de tabela.

Parâmetro

Descrição

resource_name

Nome de um recurso de tabela existente no projeto atual do MaxCompute. Retorna uma exceção se o nome for inválido ou se o recurso não existir.

O valor de retorno é um gerador. Um registro do tipo ARRAY é obtido cada vez que o chamador percorre a tabela. Tipos de coluna com suporte: BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, FLOAT, CHAR, VARCHAR, BINARY, DATE, DECIMAL, ARRAY, MAP, STRUCT.

from odps.udf import annotate
from odps.distcache import get_cache_table

@annotate('->string')
class DistCacheTableExample(object):
    def __init__(self):
        self.records = list(get_cache_table('udf_test'))
        self.counter = 0
        self.ln = len(self.records)

    def evaluate(self):
        if self.counter > self.ln - 1:
            return None
        ret = self.records[self.counter]
        self.counter += 1
        return str(ret)

Chamar uma UDF

Ativar Python 3

Os projetos do MaxCompute usam Python 2 para UDFs por padrão. Para executar uma UDF em Python 3, adicione a seguinte linha antes da instrução SQL:

SET odps.sql.python.version=cp37;

Chamar dentro do mesmo projeto

Chame a UDF da mesma forma que uma função integrada:

SET odps.sql.python.version=cp37;
SELECT my_udf(column1, column2) FROM my_table;

Chamar entre projetos

Para usar uma UDF de outro projeto (por exemplo, usar uma UDF do Projeto B no Projeto A), prefixe a chamada da função com o nome do projeto de source:

SELECT B:udf_in_other_project(arg0, arg1) AS res FROM table_t;

Para mais informações, consulte Acessar recursos entre projetos usando pacotes.

Migrar UDFs em Python 2

O Python 2 atingiu o fim da vida útil (EOL) no início de 2020.

Para novos projetos, escreva todas as UDFs Python em Python 3.

Para projetos existentes com UDFs em Python 2, proceda com cautela ao mudar para o Python 3. Duas abordagens estão disponíveis:

  • Escreva novas UDFs em Python 3 e ative o Python 3 no nível de sessão para novos jobs. Para detalhes, consulte Ativar Python 3.

  • Reescreva as UDFs existentes em Python 2 para serem compatíveis tanto com Python 2 quanto com Python 3. Para orientações, consulte Portando código Python 2 para Python 3.

Para UDFs compartilhadas entre vários projetos, escreva código compatível tanto com Python 2 quanto com Python 3.

Próximos passos