Todos os produtos
Search
Central de documentação

MaxCompute:Tabelas externas CSV e TSV

Última atualização: Sep 17, 2026

Saiba como criar, ler e gravar tabelas externas para dados CSV e TSV armazenados no Object Storage Service (OSS).

Observações de uso

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

  • O tamanho de um único arquivo não pode exceder 2 GB. É necessário dividir arquivos maiores que 2 GB.

  • O MaxCompute e o OSS devem estar na mesma região.

Tipos de dados suportados

Para obter mais informações sobre os tipos de dados do MaxCompute, consulte Data Type Version 1.0 e Data Type Version 2.0.

Para obter mais informações sobre o SmartParse, consulte Flexible type compatibility of Smart Parse.

Tipo

com.aliyun.odps.CsvStorageHandler/

TsvStorageHandler

(Integrado)

org.apache.hadoop.hive.serde2.OpenCSVSerde

(Código aberto)

TINYINT

Supported

Supported

SMALLINT

Supported

Supported

INT

Supported

Supported

BIGINT

Supported

Supported

BINARY

Not supported

Not supported

FLOAT

Supported

Supported

DOUBLE

Supported

Supported

DECIMAL(precision,scale)

Supported

Supported

VARCHAR(n)

Supported

Supported

CHAR(n)

Supported

Supported

STRING

Supported

Supported

DATE

Supported

Supported

DATETIME

Supported

Supported

TIMESTAMP

Supported

Supported

TIMESTAMP_NTZ

Supported

Not supported

BOOLEAN

Supported

Supported

ARRAY

Not supported

Not supported

MAP

Not supported

Not supported

STRUCT

Not supported

Not supported

JSON

Not supported

Not supported

Formatos de compactação suportados

Ao ler ou gravar em arquivos compactados do OSS, inclua o atributo with serdeproperties na instrução CREATE TABLE. Para obter mais informações, consulte with serdeproperties attribute parameters.

Formato de compactação

com.aliyun.odps.CsvStorageHandler/

TsvStorageHandler

(Integrado)

org.apache.hadoop.hive.serde2.OpenCSVSerde

(Código aberto)

GZIP

Supported

Supported

SNAPPY

Not supported

Supported

LZO

Not supported

Supported

ZSTD

Supported

Supported

Evolução de esquema suportada

Operação

Suportada

Descrição

Adicionar coluna

Supported

  • Não há suporte para adicionar colunas com valores padrão.

  • Não há suporte para adicionar colunas de tipos de dados complexos ou aninhados.

Remover coluna

Supported

Esta operação não é recomendada, pois pode causar incompatibilidade entre o esquema e os dados.

Alterar ordem das colunas

Supported

Esta operação não é recomendada, pois pode causar incompatibilidade entre o esquema e os dados.

Alterar tipo de dados da coluna

Supported

Para obter uma lista de conversões de tipos de dados suportadas, consulte Change Column Data Type.

Renomear coluna

Supported

Modificar comentário da coluna

Supported

O comentário deve ser uma string válida com comprimento máximo de 1.024 bytes. Caso contrário, ocorrerá um erro.

Alterar nulabilidade da coluna

Not supported

Esta operação não é suportada. As colunas aceitam valores nulos por padrão.

Configuração de parâmetros

O esquema de uma tabela externa CSV ou TSV mapeia as colunas do arquivo por posição. Se o número de colunas em um arquivo do OSS não corresponder ao número de colunas no esquema da tabela externa, use o parâmetro odps.sql.text.schema.mismatch.mode para especificar como lidar com linhas incompatíveis.

  • Se odps.sql.text.schema.mismatch.mode estiver definido como truncate, as modificações nas colunas terão os seguintes efeitos:

    • Os dados que estão em conformidade com o novo esquema são lidos conforme esperado.

    • Os dados existentes que usam o esquema antigo são lidos com base no novo esquema.

      Por exemplo, se você adicionar uma coluna a uma tabela, os dados históricos dessa coluna aparecerão como NULL durante a leitura.

  • Se odps.sql.text.schema.mismatch.mode estiver definido como ignore, as modificações nas colunas terão os seguintes efeitos:

    • Os dados que estão em conformidade com o novo esquema são lidos conforme esperado.

    • Os dados existentes que usam o esquema antigo são lidos com base no novo esquema.

      Por exemplo, se você adicionar uma coluna a uma tabela, linhas inteiras de dados históricos sem a nova coluna serão descartadas durante a leitura.

  • Se odps.sql.text.schema.mismatch.mode estiver definido como error, as modificações nas colunas terão os seguintes efeitos:

    • Os dados que estão em conformidade com o novo esquema são lidos conforme esperado.

    • Os dados existentes que usam o esquema antigo são lidos com base no novo esquema.

      Por exemplo, se você adicionar uma coluna a uma tabela, ocorrerá um erro ao tentar ler dados históricos sem a nova coluna.

Descrição de permissões

  • Ao acessar tabelas externas do OSS, o acesso aos dados ocorre por meio da função especificada no parâmetro odps.properties.rolearn, independentemente de você usar uma conta Alibaba Cloud, um usuário RAM ou uma função RAM. Portanto, crie uma função RAM e conceda a ela permissões para acessar o bucket do OSS de destino. Em seguida, configure o ARN da função no parâmetro odps.properties.rolearn. Para obter mais informações, consulte Parameters.

  • Autorize o acesso na mesma conta ou entre contas, conforme seus requisitos de negócios. Recomendamos o uso de uma política de autorização personalizada para um controle de acesso mais refinado. Para obter mais informações, consulte Authorization for external data sources.

Criar uma tabela externa

Sintaxe

Analisador de texto integrado

Formato CSV

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 'com.aliyun.odps.CsvStorageHandler'  
[WITH serdeproperties (
  ['<property_name>'='<property_value>',...]
)] 
LOCATION '<oss_location>'
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];

Formato TSV

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 'com.aliyun.odps.TsvStorageHandler'  
[WITH serdeproperties (
  ['<property_name>'='<property_value>',...]
)] 
LOCATION '<oss_location>'
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];

Analisador de código aberto integrado

CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name>
(
  <col_name> <data_type>,
  ...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
[WITH serdeproperties (
  ['<property_name>'='<property_value>',...]
)]
STORED AS TEXTFILE 
LOCATION '<oss_location>' 
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];

Parâmetros comuns

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

Parâmetros específicos de formato

Parâmetros WITH SERDEPROPERTIES

Analisador aplicável

Parâmetro

Caso de uso

Descrição

Valor

Padrão

Analisador de dados de texto integrado (CsvStorageHandler/TsvStorageHandler)

odps.text.option.gzip.input.enabled

Use esta propriedade para ler arquivos CSV ou TSV compactados no formato GZIP.

Propriedade de compactação CSV e TSV. Defina esta propriedade como True para que o MaxCompute leia arquivos compactados em GZIP. Caso contrário, a operação de leitura falhará.

  • True

  • False

False

odps.text.option.gzip.output.enabled

Use esta propriedade para gravar dados no OSS no formato compactado GZIP.

Propriedade de compactação CSV e TSV. Defina esta propriedade como True para compactar dados ao gravar no OSS. Caso contrário, os dados serão gravados sem compactação.

  • True

  • False

False

odps.text.option.header.lines.count

Use esta propriedade para ignorar as primeiras N linhas de um arquivo CSV ou TSV no OSS.

Especifica o número de linhas de cabeçalho a serem ignoradas desde o início do arquivo durante a leitura dos dados.

Inteiro não negativo

0

odps.text.option.null.indicator

Use esta propriedade para definir uma string personalizada que representa um valor NULL nos dados.

O MaxCompute analisa a string especificada como um valor NULL.

Por exemplo, para interpretar \N no arquivo como NULL, defina esta propriedade como \\N, onde o primeiro \ é um caractere de escape. Com essa configuração, a,\N,b é analisado como a, NULL, b.

string

string vazia

odps.text.option.ignore.empty.lines

Use esta propriedade para definir como lidar com linhas vazias em um arquivo CSV ou TSV.

Se True, o MaxCompute ignora linhas vazias no arquivo de dados. Se False, ele as lê.

  • True

  • False

True

odps.text.option.encoding

Use esta propriedade quando um arquivo de dados não utilizar a codificação UTF-8 padrão.

A codificação especificada aqui deve corresponder à codificação real do arquivo. Uma incompatibilidade causa falhas na leitura.

  • UTF-8

  • UTF-16

  • US-ASCII

  • GBK

UTF-8

odps.text.option.delimiter

Use esta propriedade para especificar o delimitador de coluna para arquivos CSV ou TSV.

Garanta que o delimitador especificado separe corretamente as colunas no seu arquivo de dados para evitar desalinhamento.

Caractere único

Vírgula (,)

odps.text.option.use.quote

Use esta propriedade quando um campo em um arquivo CSV ou TSV contiver quebras de linha (CRLF), aspas duplas ou o delimitador de coluna.

Quando um campo em um arquivo CSV contém uma nova linha, aspas duplas (é necessário adicionar outra " antes da " para escapá-la) ou uma vírgula, todo o campo deve ser colocado entre aspas duplas ("") como delimitador de coluna. Este parâmetro especifica se o delimitador de coluna CSV " deve ser reconhecido.

  • True

  • False

False

odps.sql.text.option.flush.header

Use esta propriedade para gravar um cabeçalho de tabela como a primeira linha em cada bloco de arquivo no OSS.

Esta propriedade aplica-se apenas a arquivos CSV.

  • True

  • False

False

odps.sql.text.schema.mismatch.mode

Use esta propriedade quando uma linha no arquivo de dados tiver um número de colunas diferente do esquema da tabela externa.

Especifica como lidar com linhas cuja contagem de colunas não corresponde ao esquema da tabela.

Nota: Este recurso não funciona se odps.text.option.use.quote estiver definido como True.

  • error: Relata um erro e interrompe a consulta.

  • truncate: Se uma linha tiver mais colunas que o esquema, o MaxCompute descarta as colunas extras. Se tiver menos colunas, o MaxCompute preenche as colunas ausentes com null.

  • ignore: Descarta toda a linha incompatível.

error

odps.text.option.zstd.input.enabled

Use esta propriedade para ler arquivos CSV ou TSV compactados no formato ZSTD.

Propriedade de compactação CSV e TSV. Defina esta propriedade como True para que o MaxCompute leia arquivos compactados em ZSTD. Caso contrário, a operação de leitura falhará.

  • True

  • False

False

odps.text.option.zstd.output.enabled

Use esta propriedade para gravar dados no OSS no formato compactado ZSTD.

Propriedade de compactação CSV e TSV. Defina esta propriedade como True para compactar dados no formato ZSTD ao gravar no OSS. Caso contrário, os dados serão gravados sem compactação.

  • True

  • False

False

odps.text.option.snappy.input.enabled

Adicione esta propriedade quando precisar ler arquivos CSV ou TSV compactados com SNAPPY

(SnappyRawCodec).

Propriedade de compactação CSV e TSV. O MaxCompute só consegue ler arquivos compactados quando este parâmetro está definido como True. Caso contrário, a operação de leitura falhará.

  • True

  • False

False

odps.text.option.snappy.output.enabled

Adicione esta propriedade quando precisar gravar dados no

OSS compactados com SNAPPY (SnappyRawCodec).

Propriedade de compactação CSV e TSV. Quando este parâmetro está definido como True, o MaxCompute grava dados no OSS com compactação SNAPPY. Caso contrário, os dados são gravados sem compactação.

  • True

  • False

False

Analisador de dados de código aberto integrado (OpenCSVSerde)

separatorChar

Use esta propriedade para especificar o delimitador de coluna para dados CSV armazenados como TEXTFILE.

Especifica o delimitador de coluna.

Um caractere único

Vírgula (,)

quoteChar

Use esta propriedade quando campos em dados CSV contiverem caracteres especiais, como o delimitador ou quebras de linha.

Especifica o caractere usado para colocar campos entre aspas.

Um caractere único

Nenhum

escapeChar

Use esta propriedade para especificar o caractere de escape para dados CSV armazenados como TEXTFILE.

Especifica o caractere usado para escapar caracteres especiais dentro de um campo.

Um caractere único

Nenhum

Parâmetros tblproperties

Analisador aplicável

Parâmetro

Caso de uso

Descrição

Valor

Padrão

Analisador de dados de código aberto integrado (OpenCSVSerde)

skip.header.line.count

Use esta propriedade para ignorar as primeiras N linhas de um arquivo CSV armazenado como TEXTFILE.

Especifica o número de linhas de cabeçalho a serem ignoradas desde o início do arquivo durante a leitura dos dados.

Inteiro não negativo

Nenhum

skip.footer.line.count

Use esta propriedade para ignorar as últimas N linhas de um arquivo CSV armazenado como TEXTFILE.

Especifica o número de linhas de rodapé a serem ignoradas no final do arquivo durante a leitura dos dados.

Inteiro não negativo

Nenhum

mcfed.mapreduce.output.fileoutputformat.compress

Use esta propriedade para gravar dados TEXTFILE no OSS com compactação.

Propriedade de compactação TEXTFILE. Se definido como True, o MaxCompute compacta os dados durante a gravação. Caso contrário, os dados são gravados sem compactação.

  • True

  • False

False

mcfed.mapreduce.output.fileoutputformat.compress.codec

Use esta propriedade para especificar o codec de compactação ao gravar dados TEXTFILE compactados no OSS.

Ao ler arquivos CSV/TSV compactados cujos nomes contenham o sufixo .bz2, .deflate, .snappy, .gz ou .zstd, nenhuma configuração adicional é necessária.

Propriedade de compactação TEXTFILE. Define o método de compactação para arquivos de dados TEXTFILE.

  • com.hadoop.compression.lzo.LzoCodec

  • com.hadoop.compression.lzo.LzopCodec

  • org.apache.hadoop.io.compress.SnappyCodec

  • com.aliyun.odps.io.compress.SnappyRawCodec

  • org.apache.hadoop.io.compress.odps.ZstandardCodec

  • org.apache.hadoop.io.compress.GzipCodec

  • org.apache.hadoop.io.compress.BZip2Codec

  • org.apache.hadoop.io.compress.DeflateCodec

Nenhum

odps.text.option.bad.row.skipping

Use esta propriedade para ignorar dados incorretos em arquivos CSV armazenados no OSS.

Controla se o MaxCompute ignora linhas consideradas dados incorretos ou relata um erro.

  • rigid: Impõe a ignorância de linhas. Esta configuração não pode ser substituída no nível de sessão ou projeto.

  • flexible: Habilita a ignorância de linhas de forma flexível. Você pode substituir esta configuração por configurações de nível de sessão ou projeto.

Nenhum

Lista de permissões e lista de bloqueios

As tabelas externas do OSS no MaxCompute suportam filtragem por lista de permissões e lista de bloqueios. Ao definir parâmetros de lista de permissões e lista de bloqueios em tblproperties, filtre quais arquivos ler de um diretório. Para obter detalhes, consulte Whitelist and blacklist.

Gravar dados

Para obter detalhes sobre a sintaxe de gravação no MaxCompute, consulte Write syntax.

Consulta e análise

BadRowSkipping

O recurso BadRowSkipping permite ignorar linhas inválidas em dados CSV que, de outra forma, causariam falha na consulta. Esta configuração controla o tratamento de erros e não afeta a análise do formato de dados subjacente.

Parâmetros

  • Parâmetro de nível de tabela: odps.text.option.bad.row.skipping

    • rigid: Força a ignorância de linhas. Esta configuração não pode ser substituída por configurações de nível de sessão ou projeto.

    • flexible: Habilita a ignorância de linhas. Esta configuração é flexível, permitindo que seja substituída por configurações de nível de sessão ou projeto.

  • Parâmetros de nível de session/project

    • O parâmetro odps.sql.unstructured.text.bad.row.skipping pode substituir um parâmetro de nível de tabela flexible, mas não um parâmetro rigid.

      • on: Habilita o recurso. Se o recurso não estiver configurado para a tabela, ele será habilitado por padrão.

      • off: Desabilita o recurso. Se a tabela estiver configurada como flexible, o recurso será desabilitado. Caso contrário, a configuração do parâmetro da tabela será usada.

      • <null> or invalid input: A configuração de nível de tabela é usada.

    • odps.sql.unstructured.text.bad.row.skipping.debug.num: Especifica o número de resultados de erro a serem impressos no stdout no Logview.

      • O valor máximo é 1000.

      • Se o valor for <=0, este recurso será desabilitado.

      • Se o valor for inválido, este recurso será desabilitado.

  • Interação entre parâmetros de nível de sessão e propriedades da tabela

    tbl property

    session flag

    resultado

    rigid

    on

    On, Forçado on

    off

    <null>, um valor inválido ou o parâmetro não está configurado

    flexible

    on

    On

    off

    Off, Desabilitado pela sessão

    <null>, um valor inválido ou o parâmetro não está configurado

    On

    Não configurado

    on

    On, Habilitado pela sessão

    off

    Off

    <null>, um valor inválido ou o parâmetro não está configurado

Exemplos

  1. Prepare os dados

    Faça upload do arquivo de dados de teste csv_bad_row_skipping.csv, que contém linhas inválidas, para um diretório no OSS, como oss-mc-test/badrow/.

  2. Crie as tabelas externas CSV

    Os exemplos a seguir mostram três cenários baseados em diferentes combinações de parâmetros de nível de tabela e nível de sessão.

    • Parâmetro da tabela: odps.text.option.bad.row.skipping = flexible | rigid | <not set>

    • Flag da sessão: odps.sql.unstructured.text.bad.row.skipping = on | off | <not set>

    Parâmetro não definido

    -- No table-level parameter is set. Queries will fail on bad rows unless overridden by the session-level flag.
    CREATE EXTERNAL TABLE test_csv_bad_data_skipping_flag
    (
      a INT,
      b INT
    )
    STORED BY 'com.aliyun.odps.CsvStorageHandler' 
    WITH serdeproperties (
      'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    )
    location '<oss://<your-bucket-name>/<your-file-path>/>';

    Ignorância flexível

    -- The table is configured to skip bad rows, but this can be disabled by the session-level flag.
    CREATE EXTERNAL TABLE test_csv_bad_data_skipping_flexible
    (
      a INT,
      b INT
    )
    STORED BY 'com.aliyun.odps.CsvStorageHandler' 
    WITH serdeproperties (
      'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    )
    location '<oss://<your-bucket-name>/<your-file-path>/>'
    tblproperties (
      'odps.text.option.bad.row.skipping' = 'flexible'   -- Enables flexible skipping, which can be disabled at the session level.
    );

    Ignorância rígida

    -- The table is configured to forcibly skip bad rows. This cannot be disabled at the session level.
    CREATE EXTERNAL TABLE test_csv_bad_data_skipping_rigid
    (
      a INT,
      b INT
    )
    STORED BY 'com.aliyun.odps.CsvStorageHandler' 
    WITH serdeproperties (
      'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    )
    location '<oss://<your-bucket-name>/<your-file-path>/>'
    tblproperties (
      'odps.text.option.bad.row.skipping' = 'rigid'  -- Forces skipping on.
    );
  3. Verifique os resultados da consulta

    Parâmetro não definido

    -- The following command enables skipping, but it is immediately overridden by the next command in this example.
    SET odps.sql.unstructured.text.bad.row.skipping=on;
    
    -- This command disables skipping and is the active setting for the SELECT query below, causing it to fail.
    SET odps.sql.unstructured.text.bad.row.skipping=off;
    
    -- You can use this command to print details of skipped rows when skipping is enabled. It has no effect here because the query fails.
    SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10;
    
    SELECT * FROM test_csv_bad_data_skipping_flag;

    A consulta falha com o seguinte erro: FAILED: ODPS-0123131:User defined function exception

    Ignorância flexível

    -- The following command enables skipping, but it is immediately overridden by the next command in this example.
    SET odps.sql.unstructured.text.bad.row.skipping=on;
    
    -- This command disables skipping, overriding the table's 'flexible' setting. It is the active setting for the SELECT query below, causing it to fail.
    SET odps.sql.unstructured.text.bad.row.skipping=off;
    
    -- Print details of up to 10 bad rows at the session level. The maximum is 1,000. A value of 0 or less disables printing.
    SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10;
    
    SELECT * FROM test_csv_bad_data_skipping_flexible;

    A consulta falha com o seguinte erro: FAILED: ODPS-0123131:User defined function exception

    Ignorância rígida

    -- This command is redundant because the 'rigid' setting already enforces skipping.
    SET odps.sql.unstructured.text.bad.row.skipping=on;
    
    -- This command attempts to disable skipping, but it is ignored because the 'rigid' table setting cannot be overridden.
    SET odps.sql.unstructured.text.bad.row.skipping=off;
    
    -- This command prints details for up to 10 bad rows that are skipped by the 'rigid' setting.
    SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10;
    
    SELECT * FROM test_csv_bad_data_skipping_rigid;

    O seguinte resultado é retornado:

    +------------+------------+
    | a          | b          | 
    +------------+------------+
    | 1          | 26         | 
    | 5          | 37         | 
    +------------+------------+

Compatibilidade de tipos flexível com Smart Parse

Para tabelas externas formatadas em CSV no OSS, o SQL do MaxCompute usa o tipo de dados 2.0 para operações de leitura e gravação. Anteriormente, apenas valores em formatos estritos eram suportados. Este recurso oferece compatibilidade flexível de tipos para ler uma ampla variedade de formatos de valores de arquivos CSV. As regras específicas de análise são detalhadas abaixo.

Tipo

Entrada como string

Saída como string

Descrição

BOOLEAN

  • "true"/"false"

  • "T"/"F"

  • "1"/"0"

  • "Yes"/"No"

  • "Y"/"N"

  • "" (Uma string vazia é analisada como NULL.)

Nota

Uma operação trim() será executada na entrada durante a análise.

  • "true"/"false"

  • "true"/"false"

  • "true"/"false"

  • "true"/"false"

  • "true"/"false"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

A análise falha se a string de entrada não for um dos valores suportados.

TINYINT

  • "0"

  • "1"

  • "-100"

  • "1,234,567" (notação de separador de milhar; vírgulas não podem estar no início ou no fim da string)

  • "1_234_567" (estilo Java; underscores não podem estar no início ou no fim da string)

  • "0.3e2" (notação científica; analisado apenas se o valor for um inteiro; caso contrário, ocorre um erro)

  • "-1e5" (notação científica)

  • "0xff" (hexadecimal, sem distinção entre maiúsculas e minúsculas)

  • "0b1001" (binário, sem distinção entre maiúsculas e minúsculas)

  • "4/2" (fração; analisado apenas se o valor for um inteiro; caso contrário, ocorre um erro)

  • "1000%" (porcentagem; analisado apenas se o valor for um inteiro; caso contrário, ocorre um erro)

  • "1000‰" (por mil; analisado apenas se o valor for um inteiro; caso contrário, ocorre um erro)

  • "1,000 $" (com símbolo de moeda)

  • "$ 1,000" (com símbolo de moeda)

  • "3M" (estilo K8s, unidade base-1000)

  • "2Gi" (estilo K8s, unidade base-1024)

  • "" (Uma string vazia é analisada como NULL.)

Nota
  • Durante a análise, a entrada passa por uma operação trim().

  • Se você usar notação de separador de milhar, como "1,234,567", defina o delimitador CSV como um caractere diferente de vírgula. Para obter mais informações, consulte o uso de odps.text.option.delimiter em with serdeproperties attributes.

  • As unidades base-1000 estilo K8s suportadas incluem K, M, G, P e T. As unidades base-1024 incluem Ki, Mi, Gi, Pi e Ti. Para obter mais informações, consulte resource-management.

  • Os símbolos de moeda suportados incluem $/¥/€/£/₩/USD/CNY/EUR/GBP/JPY/KRW/IDR/RP.

  • As strings "0", "1", "-100" e "" também podem ser analisadas corretamente no naive mode.

  • "0"

  • "1"

  • "-100"

  • "1234567"

  • "1234567"

  • "30"

  • "-100000"

  • "255"

  • "9"

  • "2"

  • "10"

  • "1"

  • "1000"

  • "1000"

  • "3000000" (1M = 1000*1000)

  • "2147483648" (1 Gi = 102410241024)

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

Inteiro de 8 bits. Ocorre um erro se o valor estiver fora do intervalo [-128, 127].

SMALLINT

Inteiro de 16 bits. Ocorre um erro se o valor estiver fora do intervalo [-32768, 32767].

INT

Inteiro de 32 bits. Ocorre um erro se o valor estiver fora do intervalo [-2147483648, 2147483647].

BIGINT

Inteiro de 64 bits. Ocorre um erro se o valor estiver fora do intervalo [-9223372036854775807, 9223372036854775807].

Nota

O valor -263 (-9223372036854775808) está fora do intervalo suportado devido a uma limitação no mecanismo SQL.

FLOAT

  • "3.14"

  • "0.314e1" (notação científica)

  • "2/5" (fração)

  • "123.45%" (porcentagem)

  • "123.45‰" (por mil)

  • "1,234,567.89" (notação de separador de milhar)

  • "1,234.56 $" (com símbolo de moeda)

  • "$ 1,234.56" (com símbolo de moeda)

  • "1.2M" (estilo K8s, unidade base-1000)

  • "2Gi" (estilo K8s, unidade base-1024)

  • "NaN" (sem distinção entre maiúsculas e minúsculas)

  • "Inf" (sem distinção entre maiúsculas e minúsculas)

  • "-Inf" (sem distinção entre maiúsculas e minúsculas)

  • "Infinity" (sem distinção entre maiúsculas e minúsculas)

  • "-Infinity" (sem distinção entre maiúsculas e minúsculas)

  • "" (Uma string vazia é analisada como NULL.)

Nota
  • A entrada passa por uma operação trim() durante a análise.

  • As strings "3.14", "0.314e1", "NaN", "Infinity", "-Infinity" e "" também podem ser analisadas corretamente no naive mode.

  • "3.14"

  • "3.14"

  • "0.4"

  • "1.2345"

  • "0.12345"

  • "1234567.89"

  • "1234.56"

  • "1234.56"

  • "1200000"

  • "2147483648"

  • "NaN"

  • "Infinity"

  • "-Infinity"

  • "Infinity"

  • "-Infinity"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

Valores especiais (sem distinção entre maiúsculas e minúsculas) incluem NaN, Inf, -Inf, Infinity e -Infinity. Ocorre um erro se um valor estiver fora do intervalo. Se a precisão exceder o limite, o valor será arredondado.

DOUBLE

  • "3.1415926"

  • "0.314e1" (notação científica)

  • "2/5" (fração)

  • "123.45%" (porcentagem)

  • "123.45‰" (por mil)

  • "1,234,567.89" (notação de separador de milhar)

  • "1,234.56 $" (com símbolo de moeda)

  • "$ 1,234.56" (com símbolo de moeda)

  • "1.2M" (estilo K8s, unidade base-1000)

  • "2Gi" (estilo K8s, unidade base-1024)

  • "NaN" (sem distinção entre maiúsculas e minúsculas)

  • "Inf" (sem distinção entre maiúsculas e minúsculas)

  • "-Inf" (sem distinção entre maiúsculas e minúsculas)

  • "Infinity" (sem distinção entre maiúsculas e minúsculas)

  • "-Infinity" (sem distinção entre maiúsculas e minúsculas)

  • "" (Uma string vazia é analisada como NULL.)

Nota
  • Durante a análise, uma operação trim() é executada na entrada.

  • As strings "3.1415926", "0.314e1", "NaN", "Infinity", "-Infinity" e "" também podem ser analisadas corretamente no naive mode.

  • "3.1415926"

  • "3.14"

  • "0.4"

  • "1.2345"

  • "0.12345"

  • "1234567.89"

  • "1234.56"

  • "1234.56"

  • "1200000"

  • "2147483648"

  • "NaN"

  • "Infinity"

  • "-Infinity"

  • "Infinity"

  • "-Infinity"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

Valores especiais (sem distinção entre maiúsculas e minúsculas) incluem NaN, Inf, -Inf, Infinity e -Infinity. Ocorre um erro se um valor estiver fora do intervalo. Se a precisão exceder o limite, o valor será arredondado.

DECIMAL

(precision, scale)

Exemplo: DECIMAL(15,2)

  • "3.358"

  • "2/5" (fração)

  • "123.45%" (porcentagem)

  • "123.45‰" (por mil)

  • "1,234,567.89" (notação de separador de milhar)

  • "1,234.56 $" (com símbolo de moeda)

  • "$ 1,234.56" (com símbolo de moeda)

  • "1.2M" (estilo K8s, unidade base-1000)

  • "2Gi" (estilo K8s, unidade base-1024)

  • "" (Uma string vazia é analisada como NULL.)

Nota
  • Durante a análise, a operação trim() é executada na entrada.

  • As strings "3.358" e "" também podem ser analisadas corretamente no naive mode.

  • "3.36" (arredondado)

  • "0.4"

  • "1.23" (arredondado)

  • "0.12" (arredondado)

  • "1234567.89"

  • "1234.56"

  • "1234.56"

  • "1200000"

  • "2147483648"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

Ocorre um erro se a parte inteira contiver mais de precision - scale dígitos. Se a parte fracionária exceder a escala especificada, o valor será arredondado.

Um erro é relatado. Se a parte fracionária exceder a escala, o valor será arredondado e truncado.

CHAR(n)

Exemplo: CHAR(7)

  • "abcdefg"

  • "abcdefghijklmn"

  • "abc"

  • "" (Uma string vazia é analisada como NULL.)

  • "abcdefg"

  • "abcdefg" (O restante da string é truncado.)

  • "abc____" (preenchido com quatro caracteres de espaço, representados por _)

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

O comprimento máximo é 255. Se uma string de entrada for menor que n, ela será preenchida com espaços à direita, mas esses espaços são ignorados nas comparações. Se uma string de entrada for maior que n, ela será truncada.

VARCHAR(n)

Exemplo: VARCHAR(7)

  • "abcdefg"

  • "abcdefghijklmn"

  • "abc"

  • "" (Uma string vazia é analisada como NULL.)

  • "abcdefg"

  • "abcdefg" (O restante da string é truncado.)

  • "abc"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

O comprimento máximo é 65.535. Se uma string de entrada for maior que n, ela será truncada.

STRING

  • "abcdefg"

  • "abc"

  • "" (Uma string vazia é analisada como NULL.)

  • "abcdefg"

  • "abc"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

O comprimento máximo é 8 MB.

DATE

  • "yyyy-MM-dd" (por exemplo, "2025-02-21")

  • "yyyyMMdd" (por exemplo, "20250221")

  • "MMM d,yyyy" (por exemplo, "Oct 1,2025")

  • "MMMM d,yyyy" (por exemplo, "October 1,2025")

  • "" (Uma string vazia é analisada como NULL.)

Nota

Você também pode definir a propriedade odps.text.option.date.io.format para controlar o formato de análise. Por exemplo, se você definir o formato como 'dd/MM/yyyy#yyyy--MM--dd', o MaxCompute poderá analisar strings como '21/02/2025' e '2025--02--21'.

  • "2000-01-01"

  • "2000-01-01"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

  • Este tipo não contém informações de hora, portanto, alterar o fuso horário não afeta a saída. O formato de saída padrão é "yyyy-MM-dd".

  • Você pode definir a propriedade odps.text.option.date.io.format para definir formatos personalizados de análise e saída. O primeiro padrão definido é usado para saída. Para sintaxe de padrões, consulte DateTimeFormatter.

TIMESTAMP_NTZ

Nota

O OpenCsvSerde não suporta este tipo porque é incompatível com o formato de dados Hive.

  • A parte de nanossegundos pode ter de 0 a 9 dígitos. Os formatos integrados suportados pelo MaxCompute são:

    • "yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]" (por exemplo, "2000-01-01 00:00:00.123")

    • "yyyy-MM-ddTHH:mm:ss[.SSSSSSSSS]" (por exemplo, "2000-01-01T00:00:00.123456789")

    • "yyyyMMddHHmmss" (por exemplo, "20000101000000")

    • "" (Uma string vazia é analisada como NULL.)

  • Você também pode definir a propriedade odps.text.option.timestamp_ntz.io.format para controlar o formato de análise. Por exemplo, se você definir o formato como 'ddMMyyyy-HHmmss', o MaxCompute poderá analisar uma string como '31102024-103055'.

  • "2000-01-01 00:00:00.123000000"

  • "2000-01-01 00:00:00.123456789"

  • "2000-01-01 00:00:00.000000000"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

  • Este tipo representa um carimbo de data/hora com precisão de nanossegundos. Ele não é afetado pelo fuso horário da sessão e sua saída assume como padrão o fuso horário UTC padrão. O formato de saída padrão é "yyyy-MM-dd HH:mm:ss.SSSSSSSSS".

  • Você pode definir a propriedade odps.text.option.timestamp_ntz.io.format para definir formatos personalizados de análise e saída. Para sintaxe de padrões, consulte DateTimeFormatter.

DATETIME

  • A parte de milissegundos pode ter de 0 a 3 dígitos. [x] representa o deslocamento do fuso horário. Supondo que o fuso horário do sistema seja Asia/Shanghai, os formatos integrados suportados pelo MaxCompute são:

    • "yyyy-MM-dd HH:mm:ss[.SSS][x]" (por exemplo, "2000-01-01 00:00:00.123")

    • "yyyy-MM-ddTHH:mm:ss[.SSS][x]" (por exemplo, "2000-01-01T00:00:00.123+0000")

    • "yyyyMMddHHmmss[x]" (por exemplo, "20000101000000+0000")

    • "" (Uma string vazia é analisada como NULL.)

  • Você também pode definir a propriedade odps.text.option.datetime.io.format para controlar o formato de análise. Por exemplo, se você definir o formato como 'yyyyMMdd-HHmmss.SSS', o MaxCompute poderá analisar uma string como '20241031-103055.123'.

Supondo que o fuso horário do sistema seja Asia/Shanghai:

  • "2000-01-01 00:00:00.123+0800"

  • "2000-01-01 08:00:00.123+0800"

  • "2000-01-01 08:00:00.000+0800"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

  • Este tipo representa um carimbo de data/hora com precisão de milissegundos. O valor de saída é afetado pelo fuso horário da sessão. O formato de saída padrão é "yyyy-MM-dd HH:mm:ss.SSSx".

  • Você pode definir a propriedade odps.sql.timezone para alterar o fuso horário do sistema, que controla o deslocamento do fuso horário do valor de saída.

  • Você também pode definir a propriedade odps.text.option.datetime.io.format para definir formatos personalizados de análise e saída. Para sintaxe de padrões, consulte DateTimeFormatter.

TIMESTAMP

  • A parte de nanossegundos pode ter de 0 a 9 dígitos. [x] representa o deslocamento do fuso horário. Supondo que o fuso horário do sistema seja Asia/Shanghai, os formatos integrados suportados pelo MaxCompute são:

    • "yyyy-MM-dd HH:mm:ss[.SSSSSSSSS][x]" (por exemplo, "2000-01-01 00:00:00.123456")

    • "yyyy-MM-ddTHH:mm:ss[.SSSSSSSSS][x]" (por exemplo, "2000-01-01T00:00:00.123+0000")

    • "yyyyMMddHHmmss[x]" (por exemplo, "20000101000000+0000")

    • "" (Uma string vazia é analisada como NULL.)

  • Você também pode definir a propriedade odps.text.option.timestamp.io.format para controlar o formato de análise. Por exemplo, se você definir o formato como 'yyyyMMdd-HHmmss', o MaxCompute poderá analisar uma string como '20240910-103055'.

(Supondo que o fuso horário do sistema seja Asia/Shanghai)

  • "2000-01-01 00:00:00.123456000+0800"

  • "2000-01-01 08:00:00.123000000+0800"

  • "2000-01-01 08:00:00.000000000+0800"

  • "" (Valores NULL são gravados como uma string vazia no arquivo CSV.)

  • Este tipo representa um carimbo de data/hora com precisão de nanossegundos. O valor de saída é afetado pelo fuso horário da sessão. O formato de saída padrão é "yyyy-MM-dd HH:mm:ss.SSSSSSSSSx".

  • Você pode definir a propriedade odps.sql.timezone para alterar o fuso horário do sistema, que controla o deslocamento do fuso horário do valor de saída.

  • Você também pode definir a propriedade odps.text.option.timestamp.io.format para definir formatos personalizados de análise e saída. Para sintaxe de padrões, consulte DateTimeFormatter.

  • Regras gerais

    • Para qualquer tipo de dados, uma string vazia no arquivo de dados CSV é analisada como NULL ao ser lida em uma tabela.

  • Tipos de dados não suportados

    • Tipos complexos (STRUCT, ARRAY, MAP): Não suportados. Valores desses tipos frequentemente contêm caracteres como a vírgula (,), que podem entrar em conflito com delimitadores CSV comuns e causar falhas na análise.

    • BINARY e INTERVAL: Atualmente não suportados. Se você precisar de suporte para esses tipos, entre em contato com o suporte técnico do MaxCompute.

  • Tipos numéricos (INT, DOUBLE, etc.)

    • Para tipos de dados numéricos como INT, SMALLINT, TINYINT, BIGINT, FLOAT, DOUBLE e DECIMAL, o MaxCompute oferece amplas capacidades de análise padrão.

    • Se você precisar analisar apenas strings numéricas básicas, defina a propriedade odps.text.option.smart.parse.level como naive em tblproperties. No modo naive, o analisador suporta apenas formatos simples como "123" e "123.456". A análise de outros formatos de string causa um erro.

  • Tipos de data e hora (DATE, TIMESTAMP, etc.)

    • A classe java.time.format.DateTimeFormatter processa todos os quatro tipos de data e hora: DATE, DATETIME, TIMESTAMP e TIMESTAMP_NTZ.

    • Formatos padrão: O MaxCompute possui vários formatos de análise integrados.

    • Formatos personalizados:

      • Defina múltiplos formatos de análise e um formato de saída configurando a propriedade odps.text.option.<date|datetime|timestamp|timestamp_ntz>.io.format em tblproperties.

      • Use o símbolo de cerquilha (#) para separar múltiplos padrões de análise.

      • Formatos personalizados têm precedência sobre os formatos integrados. O primeiro padrão personalizado é usado para saída.

      • Exemplo: Se você definir a string de formato personalizado para o tipo DATE como pattern1#pattern2#pattern3, o MaxCompute poderá analisar strings que correspondam a pattern1, pattern2 ou pattern3. No entanto, ao gravar dados em um arquivo, a saída sempre usará o formato especificado por pattern1. Para obter mais informações, consulte DateTimeFormatter.

  • Nota importante sobre o padrão de fuso horário 'z'

    • Evite usar 'z' (nome do fuso horário) em formatos personalizados, especialmente para usuários na China, pois é ambíguo.

    • Em vez disso, use 'x' (deslocamento de zona) ou 'VV' (ID do fuso horário) para o padrão de fuso horário.

    • Exemplo: 'CST' normalmente significa China Standard Time (UTC+8) na China. No entanto, quando java.time.format.DateTimeFormatter analisa 'CST', ele interpreta como US Central Standard Time (UTC-6), o que pode causar resultados inesperados de entrada ou saída.

Lógica de divisão de arquivos CSV

O analisador CSV/TSV integrado (OpenCSVSerde)

O analisador CSV/TSV integrado (OpenCSVSerde) exige que cada linha de dados em um arquivo CSV seja separada por \r\n ou caracteres semelhantes, e as colunas não devem conter \r\n. A lógica de divisão paralela e integridade de dados é a seguinte:

  • Primeiro, o arquivo é dividido pelo tamanho do split, e algumas linhas podem ser cortadas no meio.

  • Quando workers subsequentes consomem splits, todos os splits, exceto o primeiro, ignoram ativamente a linha parcial ou completa inicial.

  • Cada worker também deve consumir ativamente a linha parcial ou completa final, mesmo que ela caia dentro do intervalo do próximo split.

Este analisador suporta divisão paralela, mas não suporta escape de aspas.

O analisador CSV de código aberto (CsvStorageHandler / TsvStorageHandler)

O analisador CSV de código aberto (CsvStorageHandler / TsvStorageHandler) leva em consideração o escape de aspas ao ler arquivos CSV/TSV e suporta \r\n. Ele consegue lidar com cenários onde caracteres especiais, como aspas aninhadas ou \r\n, aparecem dentro de aspas.

Por exemplo, nos dados "a\ra","b\nb","cc""cc", o \r\n e as aspas duplas podem ser analisados e gerados corretamente, suportando valores entre linhas. No entanto, como as posições reais de quebra de linha só podem ser determinadas através da análise dos dados, o arquivo não pode ser simplesmente dividido por \r\n. Como resultado, o consumo paralelo de um único arquivo não é suportado.

Se você confirmar que as colunas de dados não contêm \r\n e que \r\n é usado apenas como delimitador de linha, habilite a divisão paralela definindo odps.sql.unstructured.data.single.file.split.enabled. Nesse caso, um arquivo grande pode ser dividido em vários splits pelo tamanho do split, e o Text Extractor integrado se alinha automaticamente aos limites de quebra de linha para garantir a integridade dos dados.

Conclusão:

  • Se os dados contiverem \r\n que não possam ser tratados como delimitador de linha, apenas o analisador CSV/TSV integrado poderá ser usado.

  • Por outro lado, se você precisar dividir um único arquivo grande em paralelo, apenas o analisador CSV Serde de código aberto poderá ser usado.

Exemplos

Pré-requisitos

  • Um MaxCompute project is created.

  • Um bucket e uma pasta do OSS disponíveis. Para obter mais informações, consulte Create a bucket e Manage folders.

    O MaxCompute suporta a criação automática de pastas no OSS. Se uma instrução SQL envolver tabelas externas e funções definidas pelo usuário (UDFs), use uma única instrução para ler e gravar nas tabelas e usar as UDFs. Você também pode criar pastas manualmente.

    O MaxCompute é implantado apenas em regiões específicas. Para evitar possíveis problemas com conexões de dados entre regiões, garanta que seu bucket do OSS esteja na mesma região do seu projeto MaxCompute.
  • Autorização

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

    • Você deve ter a permissão CreateTable no projeto MaxCompute. Para obter mais informações sobre permissões de tabela, consulte MaxCompute permissions.

Criar uma tabela externa do OSS com o analisador de texto integrado

Exemplo 1: Tabela não particionada

  1. Mapeie a tabela externa para o diretório Demo1/ do sample data. Use o comando a seguir para criar uma tabela externa do OSS.

    CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external1
    (
      vehicleId INT,
      recordId INT,
      patientId INT,
      calls INT,
      locationLatitute DOUBLE,
      locationLongtitue DOUBLE,
      recordTime STRING,
      direction STRING
    )
    STORED BY 'com.aliyun.odps.CsvStorageHandler' 
    WITH serdeproperties (
      'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    ) 
    LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo1/';
    
    -- You can run the `desc extended mc_oss_csv_external1;` command to view the schema of the created OSS external table.

    Este exemplo usa a função RAM aliyunodpsdefaultrole. Se você usar uma função RAM diferente, substitua aliyunodpsdefaultrole pelo nome da sua função RAM de destino e conceda a ela as permissões necessárias para acessar o OSS.

  2. Consulte a tabela externa não particionada.

    SELECT * FROM mc_oss_csv_external1;

    O comando retorna o seguinte resultado:

    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | vehicleid  | recordid   | patientid  | calls      | locationlatitute | locationlongtitue | recordtime     | direction  |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | 1          | 1          | 51         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | S          |
    | 1          | 2          | 13         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | NE         |
    | 1          | 3          | 48         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | NE         |
    | 1          | 4          | 30         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | W          |
    | 1          | 5          | 47         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | S          |
    | 1          | 6          | 9          | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | S          |
    | 1          | 7          | 53         | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | N          |
    | 1          | 8          | 63         | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | SW         |
    | 1          | 9          | 4          | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | NE         |
    | 1          | 10         | 31         | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | N          |
    +------------+------------+------------+------------+------------------+-------------------+------------+----------------+
  3. Grave dados na tabela externa não particionada e verifique se os dados foram gravados com êxito.

    INSERT INTO mc_oss_csv_external1 VALUES(1,12,76,1,46.81006,-92.08174,'9/14/2014 0:10','SW');
    SELECT * FROM mc_oss_csv_external1 WHERE recordId=12;

    O comando retorna o seguinte resultado:

    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | vehicleid  | recordid   | patientid  | calls      | locationlatitute | locationlongtitue | recordtime     | direction  |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | 1          | 12         | 76         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:10 | SW         |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+

    Verifique se um novo arquivo aparece no diretório Demo1/ no OSS.

    Após a gravação dos dados, visualize o arquivo de resultado gerado 20250606054845430gpwnhakujm16_M1_1_0_0-0_TableSink1-0-.csv (0,046 KB) no caminho correspondente do OSS, juntamente com o arquivo de dados original vehicle.csv (0,45 KB).

Exemplo 2: Tabela particionada

  1. Mapeie a tabela externa para o diretório Demo2/ do sample data. O comando de exemplo a seguir cria uma tabela externa particionada do OSS.

    CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external2
    (
      vehicleId INT,
      recordId INT,
      patientId INT,
      calls INT,
      locationLatitute DOUBLE,
      locationLongtitue DOUBLE,
      recordTime STRING
    )
    PARTITIONED BY (
      direction STRING
    )
    STORED BY 'com.aliyun.odps.CsvStorageHandler' 
    WITH serdeproperties (
      'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    ) 
    LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo2/';
    
    -- You can run the `DESC EXTENDED mc_oss_csv_external2;` command to view the schema of the created external table.

    Este exemplo usa a função RAM aliyunodpsdefaultrole. Se você usar uma função RAM diferente, substitua aliyunodpsdefaultrole pelo nome da sua função RAM de destino e conceda a ela as permissões necessárias para acessar o OSS.

  2. Importe os dados da partição. Se você criar uma tabela externa particionada do OSS, também deverá importar os dados da partição. Para obter mais informações, consulte OSS external tables.

    MSCK REPAIR TABLE mc_oss_csv_external2 ADD PARTITIONS;
    
    -- This is equivalent to the following statement.
    ALTER TABLE mc_oss_csv_external2 ADD PARTITION (direction = 'N') 
      PARTITION (direction = 'NE') PARTITION (direction = 'S') 
      PARTITION (direction = 'SW') PARTITION (direction = 'W');
  3. Consulte a tabela externa particionada.

    SELECT * FROM mc_oss_csv_external2 WHERE direction='NE';

    O comando retorna o seguinte resultado:

    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | vehicleid  | recordid   | patientid  | calls      | locationlatitute | locationlongtitue | recordtime     | direction  |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | 1          | 2          | 13         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | NE         |
    | 1          | 3          | 48         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | NE         |
    | 1          | 9          | 4          | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | NE         |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
  4. Grave dados na tabela externa particionada e verifique se os dados foram gravados com êxito.

    INSERT INTO mc_oss_csv_external2 PARTITION(direction='NE') VALUES(1,12,76,1,46.81006,-92.08174,'9/14/2014 0:10');
    SELECT * FROM mc_oss_csv_external2 WHERE direction='NE' AND recordId=12;

    O comando retorna o seguinte resultado:

    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | vehicleid  | recordid   | patientid  | calls      | locationlatitute | locationlongtitue | recordtime     | direction  |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | 1          | 12         | 76         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:10 | NE         |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+

    Verifique se um novo arquivo foi gerado no diretório Demo2/direction=NE no OSS.

    O arquivo de dados de partição gerado automaticamente 20250606062610590gocsdsoujm16_M1_1_0_0-0_TableSink1-0-.csv pode ser visto na lista de arquivos do OSS, indicando que os dados foram gravados com êxito no caminho de partição correspondente no OSS.

Exemplo 3: Dados compactados

Este exemplo mostra como criar uma tabela externa CSV compactada em GZIP e executar operações de leitura e gravação.

  1. Crie uma tabela interna e insira dados de teste para um teste de gravação subsequente.

    CREATE TABLE vehicle_test(
      vehicleid INT, 
      recordid INT, 
      patientid INT, 
      calls INT, 
      locationlatitute DOUBLE, 
      locationlongtitue DOUBLE, 
      recordtime STRING, 
      direction STRING
    );
    
    INSERT INTO vehicle_test VALUES (1,1,51,1,46.81006,-92.08174,'9/14/2014 0:00','S');
  2. Crie uma tabela externa CSV compactada em GZIP e mapeie-a para o diretório Demo3/ (que contém dados compactados) do sample data. O comando de exemplo a seguir cria a tabela externa do OSS.

    CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external3
    (
      vehicleId INT,
      recordId INT,
      patientId INT,
      calls INT,
      locationLatitute DOUBLE,
      locationLongtitue DOUBLE,
      recordTime STRING,
      direction STRING
    )
    PARTITIONED BY (dt STRING)
    STORED BY 'com.aliyun.odps.CsvStorageHandler' 
    WITH serdeproperties (
      'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole',
      'odps.text.option.gzip.input.enabled'='true',
      'odps.text.option.gzip.output.enabled'='true' 
    ) 
    LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo3/';
    
    -- Import partition data.
    MSCK REPAIR TABLE mc_oss_csv_external3 ADD PARTITIONS;
    
    -- You can run the `DESC EXTENDED mc_oss_csv_external3;` command to view the schema of the created external table.

    Este exemplo usa a função RAM aliyunodpsdefaultrole. Se você usar uma função RAM diferente, substitua aliyunodpsdefaultrole pelo nome da sua função RAM de destino e conceda a ela as permissões necessárias para acessar o OSS.

  3. Use um cliente MaxCompute para ler dados do OSS:

    Nota

    Se os dados compactados no OSS estiverem em um formato de dados de código aberto, adicione o comando set odps.sql.hive.compatible=true; antes da instrução SQL e envie-os juntos para execução.

    --Enable a full table scan for the current session only.
    SET odps.sql.allow.fullscan=true;
    SELECT recordId, patientId, direction FROM mc_oss_csv_external3 WHERE patientId > 25;

    O comando retorna o seguinte resultado:

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

    Execute o comando INSERT OVERWRITE ou INSERT INTO em uma tabela externa a partir do cliente MaxCompute para gravar dados no OSS.

    INSERT INTO TABLE mc_oss_csv_external3 PARTITION (dt='20250418') SELECT * FROM vehicle_test;

    Após a execução bem-sucedida do comando, visualize o arquivo exportado no diretório do OSS.

Criar uma tabela externa com linha de cabeçalho

Crie um diretório Demo11 no bucket oss-mc-test do sample data e execute as seguintes instruções:

--Create the external table.
CREATE EXTERNAL TABLE mf_oss_wtt
(
  id BIGINT,
  name STRING,
  tran_amt DOUBLE
)
STORED BY 'com.aliyun.odps.CsvStorageHandler'
WITH serdeproperties (
  'odps.text.option.header.lines.count' = '1',
  'odps.sql.text.option.flush.header' = 'true',
  'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
)
LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo11/';

--Insert data.
INSERT OVERWRITE TABLE mf_oss_wtt VALUES (1, 'val1', 1.1),(2, 'value2', 1.3);

--Query data.
--When you create the table, you can define all columns as STRING. Otherwise, an error occurs when the header is read.
--Alternatively, add the 'odps.text.option.header.lines.count' = '1' parameter to the table definition to skip the header.
SELECT * FROM mf_oss_wtt;

Este exemplo usa a função RAM aliyunodpsdefaultrole. Se você usar uma função RAM diferente, substitua aliyunodpsdefaultrole pelo nome da sua função RAM de destino e conceda a ela as permissões necessárias para acessar o OSS.

O comando retorna o seguinte resultado:

+----------+--------+------------+
| id       | name   | tran_amt   |
+----------+--------+------------+
| 1        | val1   | 1.1        |
| 2        | value2 | 1.3        |
+----------+--------+------------+

Criar uma tabela externa com colunas incompatíveis

  1. Crie um diretório demo no bucket oss-mc-test do sample data e faça upload do arquivo test.csv. O arquivo test.csv contém o seguinte conteúdo:

    1,kyle1,this is desc1
    2,kyle2,this is desc2,this is two
    3,kyle3,this is desc3,this is three, I have 4 columns
  2. Crie as tabelas externas.

    1. Defina o método de tratamento para linhas com contagens de colunas inconsistentes como TRUNCATE.

      -- Drop the table.
      DROP TABLE test_mismatch;
      -- Create the external table.
      CREATE EXTERNAL TABLE IF NOT EXISTS test_mismatch
      (
        id string,
        name string,
        dect string,
        col4 string
      )
      STORED BY 'com.aliyun.odps.CsvStorageHandler'
      WITH serdeproperties (
        'odps.sql.text.schema.mismatch.mode' = 'truncate',
        'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole')
      LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/';
    2. Especifique o método de tratamento para linhas com contagens de colunas inconsistentes como IGNORE.

      -- Drop the table.
      DROP TABLE test_mismatch01;
      -- Create the external table.
      CREATE EXTERNAL TABLE IF NOT EXISTS test_mismatch01
      (
        id STRING,
        name STRING,
        dect STRING,
        col4 STRING
      )
      STORED BY 'com.aliyun.odps.CsvStorageHandler'
      WITH serdeproperties ('odps.sql.text.schema.mismatch.mode' = 'ignore')
      LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/';
    3. Consulte os dados nas tabelas.

      • Consulte a tabela test_mismatch.

        SELECT * FROM test_mismatch;
        
        --Returned result
        +----+-------+---------------+---------------+
        | id | name  | dect          | col4          |
        +----+-------+---------------+---------------+
        | 1  | kyle1 | this is desc1 | NULL          |
        | 2  | kyle2 | this is desc2 | this is two   |
        | 3  | kyle3 | this is desc3 | this is three |
        +----+-------+---------------+---------------+
      • Consulte a tabela test_mismatch01.

        SELECT * FROM test_mismatch01;
        
        --Returned result
        +----+-------+----------------+-------------+
        | id | name  | dect           | col4        |
        +----+-------+----------------+-------------+
        | 2  | kyle2 | this is desc2  | this is two  
        +----+-------+----------------+-------------+

Criar uma tabela externa com o analisador de código aberto

Este exemplo mostra como usar o analisador de código aberto integrado para criar uma tabela externa do OSS que lê um arquivo separado por vírgulas, ignorando as linhas de cabeçalho e rodapé.

  1. Crie um diretório demo-test no bucket oss-mc-test do sample data e faça upload do arquivo test.csv.

    O arquivo de teste contém os seguintes dados:

    1,1,51,1,46.81006,-92.08174,9/14/2014 0:00,S
    1,2,13,1,46.81006,-92.08174,9/14/2014 0:00,NE
    1,3,48,1,46.81006,-92.08174,9/14/2014 0:00,NE
    1,4,30,1,46.81006,-92.08174,9/14/2014 0:00,W
    1,5,47,1,46.81006,-92.08174,9/14/2014 0:00,S
    1,6,9,1,46.81006,-92.08174,9/15/2014 0:00,S
    1,7,53,1,46.81006,-92.08174,9/15/2014 0:00,N
    1,8,63,1,46.81006,-92.08174,9/15/2014 0:00,SW
    1,9,4,1,46.81006,-92.08174,9/15/2014 0:00,NE
    1,10,31,1,46.81006,-92.08174,9/15/2014 0:00,N
  2. Crie a tabela externa, especifique a vírgula como separador e defina parâmetros para ignorar as linhas de cabeçalho e rodapé.

    CREATE EXTERNAL TABLE ext_csv_test08
    (
      vehicleId INT,
      recordId INT,
      patientId INT,
      calls INT,
      locationLatitute DOUBLE,
      locationLongtitue DOUBLE,
      recordTime STRING,
      direction STRING
    )
    ROW FORMAT serde 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
    WITH serdeproperties (
    "separatorChar" = ",",
    'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    )
    stored AS textfile
    location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/***/'
    -- Set parameters to ignore the header and footer rows.
    TBLPROPERTIES (
    "skip.header.line.COUNT"="1",
    "skip.footer.line.COUNT"="1"
    )
    ;
  3. Leia dados da tabela externa.

    SELECT * FROM ext_csv_test08;
    
    -- The result includes 8 rows of data because the header and footer rows are ignored.
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | vehicleid  | recordid   | patientid  | calls      | locationlatitute | locationlongtitue | recordtime     | direction  |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    | 1          | 2          | 13         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | NE         |
    | 1          | 3          | 48         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | NE         |
    | 1          | 4          | 30         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | W          |
    | 1          | 5          | 47         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | S          |
    | 1          | 6          | 9          | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | S          |
    | 1          | 7          | 53         | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | N          |
    | 1          | 8          | 63         | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | SW         |
    | 1          | 9          | 4          | 1          | 46.81006         | -92.08174         | 9/15/2014 0:00 | NE         |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+

Criar uma tabela externa CSV com tipos de tempo personalizados

Para obter detalhes sobre formatos de análise e saída para tipos de tempo personalizados em CSV, consulte Flexible type compatibility with Smart Parse.

  1. Crie uma tabela externa CSV que use vários tipos de dados de tempo, como DATE, DATETIME, TIMESTAMP e TIMESTAMP_NTZ.

    CREATE EXTERNAL TABLE test_csv
    (
      col_date DATE,
      col_datetime DATETIME,
      col_timestamp TIMESTAMP,
      col_timestamp_ntz TIMESTAMP_NTZ
    )
    STORED BY 'com.aliyun.odps.CsvStorageHandler'
    LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/'
    WITH serdeproperties (
      'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    )
    TBLPROPERTIES (
      'odps.text.option.date.io.format' = 'MM/dd/yyyy',
      'odps.text.option.datetime.io.format' = 'yyyy-MM-dd-HH-mm-ss x',
      'odps.text.option.timestamp.io.format' = 'yyyy-MM-dd HH-mm-ss VV',
      'odps.text.option.timestamp_ntz.io.format' = 'yyyy-MM-dd HH:mm:ss.SS'
    );
    
    INSERT OVERWRITE test_csv 
      VALUES(DATE'2025-02-21', DATETIME'2025-02-21 08:30:00', TIMESTAMP'2025-02-21 12:30:00', TIMESTAMP_NTZ'2025-02-21 16:30:00.123456789');
  2. Após a inserção dos dados, o conteúdo do arquivo CSV é o seguinte:

    02/21/2025,2025-02-21-08-30-00 +08,2025-02-21 12-30-00 Asia/Shanghai,2025-02-21 16:30:00.12
  3. Consulte os dados novamente para visualizar o resultado.

    SELECT * FROM test_csv;

    O comando retorna o seguinte resultado:

    +------------+---------------------+---------------------+------------------------+
    | col_date   | col_datetime        | col_timestamp       | col_timestamp_ntz      |
    +------------+---------------------+---------------------+------------------------+
    | 2025-02-21 | 2025-02-21 08:30:00 | 2025-02-21 12:30:00 | 2025-02-21 16:30:00.12 |
    +------------+---------------------+---------------------+------------------------+

Perguntas frequentes

Erro de incompatibilidade de contagem de colunas

  • Sintoma

    Este erro ocorre quando a contagem de colunas em uma linha de um arquivo CSV ou TSV não corresponde à definida no DDL da tabela externa. O MaxCompute relata um erro semelhante a FAILED: ODPS-0123131:User defined function exception - Traceback:java.lang.RuntimeException: SCHEMA MISMATCH:xxx.

  • Resolução

    Controle como o MaxCompute lida com a incompatibilidade definindo o parâmetro odps.sql.text.schema.mismatch.mode no nível de sessão:

    • SET odps.sql.text.schema.mismatch.mode=error: Falha na consulta quando ocorre uma incompatibilidade de contagem de colunas. Este é o comportamento padrão.

    • SET odps.sql.text.schema.mismatch.mode=truncate: Se uma linha tiver mais colunas do que o definido no DDL da tabela externa, as colunas extras serão descartadas. Se uma linha tiver menos colunas, as colunas ausentes serão preenchidas com NULL.