Todos os produtos
Search
Central de documentação

MaxCompute:Storage handler personalizado

Última atualização: Sep 15, 2026

Este tópico descreve como criar uma tabela externa do OSS com um storage handler personalizado e como ler e gravar dados nessa tabela.

Observações de uso

  • Tabelas externas do OSS não suportam a propriedade de cluster.

  • O tamanho máximo de um único arquivo é 2 GB. Divida arquivos maiores que 2 GB.

Crie uma tabela externa

Sintaxe

CREATE EXTERNAL TABLE [IF NOT EXISTS] mc_oss_extable_name
(
  col_name data_type,
  ...
)
[comment table_comment]
[partitioned BY (col_name data_type, ...)] 
stored BY '<YOUR_DEFINED_STORAGEHANDLER>' 
WITH serdeproperties (
  ['property_name'='property_value',...]
) 
location 'oss_location' 
USING 'jar_name';

Por padrão, um storage handler personalizado não executa fragmentação de dados para evitar problemas de integridade. Se o seu handler processar dados fragmentados, execute o comando abaixo para ativar a fragmentação e iniciar múltiplos mappers.

SET odps.sql.unstructured.data.single.file.split.enabled=true;

Parâmetros comuns

Para obter mais informações sobre parâmetros comuns, consulte Basic syntax parameters.

Parâmetros específicos

Parâmetro

Obrigatório

Descrição

your_defined_storagehandler

Sim

Storage handler personalizado implementado como função definida pelo usuário (UDF) do MaxCompute. Para saber mais sobre o desenvolvimento de UDFs, consulte Develop UDFs.

jar_name

Sim

Pacote JAR com o código do storage handler personalizado. Adicione este pacote JAR como recurso ao projeto MaxCompute.

Para mais detalhes sobre como adicionar recursos, consulte Resource operations.

resource_name

Não

Se você usar uma classe SerDe personalizada, especifique os recursos JAR dependentes.

Esses recursos devem conter a classe SerDe personalizada e estar adicionados ao projeto MaxCompute.

Consulte Resource operations para instruções sobre adição de recursos.

Gravar dados

Para obter detalhes sobre a sintaxe de gravação do MaxCompute, consulte Write data to OSS.

Consultar e analisar dados

Exemplo: Crie uma tabela externa do OSS

Este exemplo demonstra como mapear uma tabela externa para o diretório SampleData/ descrito em Appendix: Prepare sample data. O diretório está preparado para uso com um storage handler personalizado. Siga o procedimento abaixo:

  1. Pré-requisitos

    • Um MaxCompute project is created.

    • Disponibilidade de um bucket e uma pasta no OSS. Para obter mais informações, consulte Create a bucket e Manage folders.

      O MaxCompute permite a criação automática de pastas no OSS. Quando instruções SQL envolvem tabelas externas e funções definidas pelo usuário (UDFs), use um único comando para ler, gravar e executar as UDFs. Também é possível criar as pastas manualmente.

      O MaxCompute está disponível apenas em regiões específicas. Para evitar problemas de conexão entre regiões, mantenha o bucket do OSS na mesma região do projeto MaxCompute.
    • Autorização

      • Você deve ter permissões de acesso ao OSS. Acesse tabelas externas do OSS com uma conta Alibaba Cloud, um usuário do Resource Access Management (RAM) ou uma função RAM. Para obter detalhes sobre autorização, consulte Authorize access in STS mode for OSS.

      • A permissão CreateTable no projeto MaxCompute é obrigatória. Para saber mais sobre permissões de tabela, consulte MaxCompute permissions.

  2. Use o MaxCompute Studio para criar as classes Java TextExtractor.java, TextOutputer.java, SplitReader.java e TextStorageHandler.java. Para obter orientações sobre desenvolvimento Java, consulte Develop UDFs.

  3. Use o recurso de empacotamento com um clique do MaxCompute Studio para empacotar TextStorageHandler.java e carregá-lo como recurso do MaxCompute.

    Suponha que o recurso receba o nome javatest-1.0-SNAPSHOT.jar. Para obter instruções completas sobre empacotamento, upload e registro de recursos, consulte Package, upload, and register.

    Nota

    Se houver múltiplas dependências, empacote cada uma individualmente e faça o upload como recursos separados no MaxCompute.

  4. Execute o comando a seguir para criar a tabela externa do OSS:

    CREATE EXTERNAL TABLE ambulance_data_txt_external
    (
      vehicleId INT,
      recordId INT,
      patientId INT,
      calls INT,
      locationLatitute DOUBLE,
      locationLongtitue DOUBLE,
      recordTime STRING,
      direction STRING
    )
    stored BY 'com.aliyun.odps.udf.example.text.TextStorageHandler' 
      WITH serdeproperties (
        'delimiter'='|',  
        'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
      )
    location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/SampleData/'
    USING 'javatest-1.0-SNAPSHOT.jar'; 
    
    -- You can run the 'desc extended ambulance_data_txt_external;' command to view the schema of the created external table.
    Nota

    O parâmetro delimiter é uma propriedade personalizada que define o separador de colunas no arquivo do OSS. Especifique qualquer string válida como delimitador.

  5. Leia dados do OSS. Exemplo de comando:

    SELECT recordId, patientId, direction FROM ambulance_data_txt_external WHERE patientId > 25;

    Resultado retornado:

    +----------+-----------+-----------+
    | recordid | patientid | direction |
    +----------+-----------+-----------+
    | 1        | 51        | S         |
    | 3        | 48        | NE        |
    | 4        | 30        | W         |
    | 5        | 47        | S         |
    | 7        | 53        | N         |
    | 8        | 63        | SW        |
    | 10       | 31        | N         |
    +----------+-----------+-----------+
  6. Grave dados na tabela externa do OSS.

    INSERT INTO ambulance_data_txt_external VALUES (1,16,76,1,'46.81006','-92.08174','9/14/2014 0:10','SW');
    
    -- Query the table again to check whether the data is written. You can also check whether a new file is generated in the OSS directory.
    SELECT * FROM ambulance_data_txt_external WHERE recordId='16';

Perguntas frequentes

Por que recebo o erro ODPS-0123131 ao ler um campo DATETIME de dados não estruturados com um extrator personalizado?

  • Sintoma

    Ao usar um extrator personalizado para ler dados não estruturados, se um campo for do tipo DATETIME (por exemplo, 2019-11-11 06:43:36), ocorrerá o seguinte erro:

    FAILED: ODPS-0123131:User defined function exception - Traceback:
    java.lang.IllegalArgumentException
        at java.sql.Date.valueOf(Date.java:143)
        at com.aliyun.odps.udf.example.text.TextExtractor.textLineToRecord(TextExtractor.java:194)
        at com.aliyun.odps.udf.example.text.TextExtractor.extract(TextExtractor.java:153)
        at com.aliyun.odps.udf.ExtractorHandler.extract(ExtractorHandler.java:120)       
  • Causa

    Esse erro origina-se do código Date.valueOf(parts[i]). A função java.sql.Date.valueOf() aceita apenas strings no formato "yyyy-[m]m-[d]d" e não suporta informações de hora.

  • Solução

    1. Adicione a dependência Joda-Time e importe as classes necessárias no código.

      -- Dependency.
      <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.10</version>
      </dependency> 
      -- Import information.
      import org.joda.time.DateTime;
      import org.joda.time.format.DateTimeFormat;                           
    2. Use a função DateTimeFormat.forPattern() do Joda-Time para analisar a string com data e hora. Em seguida, crie um objeto java.sql.Date a partir do valor analisado.

      record.setDate(index, new Date(DateTime.parse(parts[i], DateTimeFormat.forPattern("yyyy-MM-dd HH:mi:ss")).getMillis()));                           
    3. Faça o upload do pacote JAR gerado para o projeto do extrator usando o cliente MaxCompute.

      add jar /Users/gary/big_data/odps/text_extractor/target/text_extractor-1.0-SNAPSHOT.jar      

      O caminho /Users/gary/big_data/odps/text_extractor/target/text_extractor-1.0-SNAPSHOT.jar refere-se à localização local do pacote JAR.

    4. Carregue o pacote JAR de terceiros Joda-Time usando o cliente MaxCompute.

      add jar /Users/gary/.m2/repository/joda-time/joda-time/2.10/joda-time-2.10.jar                         

      O caminho /Users/gary/.m2/repository/joda-time/joda-time/2.10/joda-time-2.10.jar indica a localização local do pacote JAR de terceiros Joda-Time.

    5. Envie os dados de teste para o diretório especificado no OSS. Suponha que o arquivo se chame video_play_log.txt. Dados de exemplo:

      5c661071dba64d5080c91da085ff1073^music-click-fast_forward^26.12.XX.XX^2019-11-11 06:43:36                           
    6. Leia os dados da tabela externa.

      select * from <project_name>.video_play_log;

      Resultado retornado:

      +------+-------+---+----------------+
      | uuid  | action  | ip  | time      |
      +------+-------+---+----------------+
      | 5c661071dba64d5080c91da085ff1073 | music-click-fast_forward | 26.12.XX.XX | 2019-11-11 06:43:36 |
      +------+-------+---+----------------+