自定义解析器

本文为您介绍通过自定义解析器创建OSS外部表以及读取和写入数据的方法。

前提条件

  • 已具备访问OSS的权限。阿里云账号(主账号)、RAM用户或RAMRole身份可以访问OSS外部表,授权信息请参见OSSSTS模式授权

  • (可选)已准备好OSS存储空间(Bucket)、OSS目录及OSS数据文件。具体操作请参见创建存储空间管理目录简单上传

    MaxCompute已支持在OSS侧自动创建目录,对于携带外部表及UDFSQL语句,您可以通过一条SQL语句执行读写外部表及UDF的操作。原手动创建目录方式仍然支持。
  • 已创建MaxCompute项目。具体操作请参见创建MaxCompute项目

    由于MaxCompute只在部分地域部署,跨地域的数据连通性可能存在问题,因此建议BucketMaxCompute项目所在地域保持一致。
  • 已具备在MaxCompute项目中创建表(CreateTable)的权限。表操作的权限信息请参见MaxCompute权限

使用限制

  • OSS外部表不支持cluster属性。

  • 单个文件大小不能超过3 GB,如果文件过大,建议拆分。

注意事项

自定义解析器默认不会对数据分片,以避免解析器出现正确性问题,如果您确认能够处理分片,可通过如下命令启用数据分片功能,即启动多个Mapper。

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

创建外部表

语法说明

CREATE EXTERNAL TABLE [IF NOT EXISTS] mc_oss_extable_name
(
  col_name date_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';

通过其他格式创建OSS外部表详情,请参见OSS外部表

公共参数

公共参数说明请参见基础语法参数说明

独有参数

参数名称

是否必填

说明

your_defined_storagehandler

通过编写MaxCompute UDF自定义的解析器,更多编写MaxCompute UDF信息,请参见开发UDF

jar_name

指定自定义解析器代码对应的JAR包,该JAR包需要添加为MaxCompute项目资源。

更多添加资源信息,请参见资源操作

resource_name

当您使用自定义的serde class时,需要指定依赖的资源。资源中包含了自定义的serde class

serde class相关的JAR包需要添加为MaxCompute项目资源。

更多添加资源信息,请参见资源操作

数据写入

MaxCompute写入语法详情,请参见将数据写入OSS

查询分析

示例:通过自定义解析器创建OSS外部表

附录:准备示例数据中的SampleData/(自定义解析器)目录建立映射关系。操作流程如下:

  1. 使用MaxCompute Studio创建TextExtractor.javaTextExtractor.javaSplitReader.javaTextStorageHandler.java四个Java类。更多开发Java程序详情,请参见开发UDF

  2. 通过MaxCompute Studio的一键式打包功能,将其中的TextStorageHandler.java打包并上传为MaxCompute资源。

    假设资源名称为javatest-1.0-SNAPSHOT.jar。更多打包上传信息,请参见打包、上传及注册

    说明

    如果有多个依赖请分别打包后上传为MaxCompute资源。

  3. 执行如下命令创建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'; 
    
    -- 您可以执行desc extended ambulance_data_txt_external;命令查看创建好的外部表结构信息。
    说明

    其中delimiter是用户自定义的、用来决定OSS文件每行数据不同列值之间的分隔符,用户可以选择任意一个合法的字符串。

  4. OSS读取数据,命令示例如下。

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

    返回结果如下。

    +----------+-----------+-----------+
    | recordid | patientid | direction |
    +----------+-----------+-----------+
    | 1        | 51        | S         |
    | 3        | 48        | NE        |
    | 4        | 30        | W         |
    | 5        | 47        | S         |
    | 7        | 53        | N         |
    | 8        | 63        | SW        |
    | 10       | 31        | N         |
    +----------+-----------+-----------+
  5. OSS外部表写入数据。

    INSERT INTO ambulance_data_txt_external VALUES (1,16,76,1,'46.81006','-92.08174','9/14/2014 0:10','SW');
    
    -- 再次查询看是否写入成功;也可看oss目录下是否生成了新文件。
    SELECT * FROM ambulance_data_txt_external WHERE recordId='16';