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
Para obter informações sobre a sintaxe SELECT, consulte Read data from OSS.
Para obter orientações sobre otimização de planos de consulta, consulte Query optimization.
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:
-
Pré-requisitos
-
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.
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.
-
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.NotaSe houver múltiplas dependências, empacote cada uma individualmente e faça o upload como recursos separados no MaxCompute.
-
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.NotaO parâmetro delimiter é uma propriedade personalizada que define o separador de colunas no arquivo do OSS. Especifique qualquer string válida como delimitador.
-
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 | +----------+-----------+-----------+ -
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çãojava.sql.Date.valueOf()aceita apenas strings no formato"yyyy-[m]m-[d]d"e não suporta informações de hora. -
Solução
-
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; -
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())); -
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.jarO caminho
/Users/gary/big_data/odps/text_extractor/target/text_extractor-1.0-SNAPSHOT.jarrefere-se à localização local do pacote JAR. -
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.jarO caminho
/Users/gary/.m2/repository/joda-time/joda-time/2.10/joda-time-2.10.jarindica a localização local do pacote JAR de terceiros Joda-Time. -
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 -
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 | +------+-------+---+----------------+
-