本文为您介绍CSV、TSV、纯TEXTFILE格式的OSS外部表的创建、读取及写入方法。
前提条件
已具备访问OSS的权限。阿里云账号(主账号)、RAM用户或RAMRole身份可以访问OSS外部表,授权信息请参见OSS的STS模式授权。
(可选)已准备好OSS存储空间(Bucket)、OSS目录及OSS数据文件。具体操作请参见创建存储空间、管理目录和简单上传。
MaxCompute已支持在OSS侧自动创建目录,对于携带外部表及UDF的SQL语句,您可以通过一条SQL语句执行读写外部表及UDF的操作。原手动创建目录方式仍然支持。
已创建MaxCompute项目。具体操作请参见创建MaxCompute项目。
由于MaxCompute只在部分地域部署,跨地域的数据连通性可能存在问题,因此建议Bucket与MaxCompute项目所在地域保持一致。
已具备在MaxCompute项目中创建表(CreateTable)的权限。表操作的权限信息请参见MaxCompute权限。
使用限制
OSS外部表不支持cluster属性。
单个文件大小不能超过3 GB,如果文件过大,建议拆分。
数据类型支持
下表中表示支持,
表示不支持。
更多有关SmartParse的说明,请参见Smart Parse更灵活的类型能力。
数据类型 | com.aliyun.odps.CsvStorageHandler (内置文本数据解析器) | org.apache.hadoop.hive.serde2.OpenCSVSerde (内置开源数据解析器) |
TINYINT | ||
SMALLINT | ||
INT | ||
BIGINT | ||
BINARY | ||
FLOAT | ||
DOUBLE | ||
DECIMAL(precision,scale) | ||
VARCHAR(n) | ||
CHAR(n) | ||
STRING | ||
DATE | ||
DATETIME | ||
TIMESTAMP | ||
TIMESTAMP_NTZ | ||
BOOLEAN | ||
ARRAY | ||
MAP | ||
STRUCT | ||
JSON |
压缩格式支持
当您需要读写压缩属性的OSS文件时,需要在建表语句中添加with serdeproperties
属性配置,详情请参见with serdeproperties属性参数。
压缩格式 | com.aliyun.odps.CsvStorageHandler (内置文本数据解析器) | org.apache.hadoop.hive.serde2.OpenCSVSerde (内置开源数据解析器) |
GZIP | ||
SNAPPY | ||
LZO |
创建外部表
语法结构
各格式的外部表语法结构详情,请参见OSS外部表。
内置文本数据解析器
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>',...)];
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>',...)];
内置开源数据解析器
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>',...)];
公共参数
公共参数说明请参见基础语法参数说明。
独有参数
with serdeproperties属性参数
property_name | 使用场景 | 说明 | property_value | 默认值 |
odps.text.option.gzip.input.enabled | 当需要读取以GZIP方式压缩的CSV或TSV文件数据时,请添加该属性。 | CSV、TSV压缩属性。配置该参数值为True时,MaxCompute才可以正常读取压缩文件,否则会读取失败。 |
| False |
odps.text.option.gzip.output.enabled | 当需要将数据以GZIP压缩方式写入OSS时,请添加该属性。 | CSV、TSV压缩属性。配置该参数值为True时,MaxCompute才能将数据以GZIP压缩方式写入OSS,否则不压缩。 |
| False |
odps.text.option.header.lines.count | 当OSS数据文件为CSV或TSV,且需要忽略OSS数据文件中的前N行时,请添加该属性。 | MaxCompute读取OSS数据文件时,会忽略指定的行数。 | 非负整数 | 0 |
odps.text.option.null.indicator | 当OSS数据文件为CSV或TSV,且需要定义OSS数据文件中NULL的解析规则时,请添加该属性。 | 通过该参数配置的字符串会被解析为SQL中的NULL。例如 | 字符串 | 空字符串 |
odps.text.option.ignore.empty.lines | 当OSS数据文件为CSV或TSV,且需要定义OSS数据文件中空行的处理规则时,请添加该属性。 | 配置该参数值为True时,MaxCompute会忽略数据文件中的空行,否则会读取空行。 |
| True |
odps.text.option.encoding | 当OSS数据文件为CSV或TSV,且OSS数据文件编码规则非默认编码规则时,请添加该属性。 | 确保此处配置的编码规则与OSS数据文件编码规则保持一致,否则MaxCompute无法成功读取数据。 |
| UTF-8 |
odps.text.option.delimiter | 当需要明确CSV或TSV数据文件的列分隔符时,请添加该属性。 | 确保此处配置的列分隔符可以正确读取OSS数据文件的每一列,否则MaxCompute读取的数据会出现错位问题。 | 单个字符 | 半角逗号(,) |
odps.text.option.use.quote | 当CSV或TSV数据文件中的字段包含换行(CRLF)、双引号或英文逗号时,请添加该属性。 | 当CSV某个字段中包含换行、双引号(需要在 |
| False |
separatorChar | 当需要明确以TEXTFILE格式保存的CSV数据的列分隔符时,请添加该属性。 | 指定CSV数据列分隔符。 | 单个字符串 | 半角逗号(,) |
quoteChar | 当以TEXTFILE格式保存的CSV数据中的字段包含换行、双引号或英文逗号时,请添加该属性。 | 指定CSV数据的引用符。 | 单个字符串 | 无 |
escapeChar | 当需要明确以TEXTFILE格式保存的CSV数据的转义规则时,请添加该属性。 | 指定CSV数据的转义符。 | 单个字符串 | 无 |
odps.sql.text.option.flush.header | 在往OSS写数据的时候,文件块的第一行为表头。 | 只有针对CSV文件格式生效。 |
| False |
odps.sql.text.schema.mismatch.mode | 当读取的OSS文件的数据列数和外部表的Schema列数不一致时。 | 指定对于列数不一致行的处理方式。 说明:odps.text.option.use.quote参数值为True时,该功能不生效。 |
| error |
tblproperties属性参数
property_name | 使用场景 | 说明 | property_value | 默认值 |
skip.header.line.count | 当需要忽略以TEXTFILE格式保存的CSV文件中的前N行数据时,请添加该属性。 | MaxCompute读取OSS数据时,会忽略从首行开始指定行数的数据。 | 非负整数 | 无 |
skip.footer.line.count | 当需要忽略以TEXTFILE格式保存的CSV文件中的后N行数据时,请添加该属性。 | MaxCompute读取OSS数据时,会忽略从尾行开始指定行数的数据。 | 非负整数 | 无 |
mcfed.mapreduce.output.fileoutputformat.compress | 当需要将TEXTFILE数据文件以压缩方式写入OSS时,请添加该属性。 | TEXTFILE压缩属性。配置该参数值为True时,MaxCompute才可以将TEXTFILE数据文件以压缩方式写入OSS,否则不压缩。 |
| False |
mcfed.mapreduce.output.fileoutputformat.compress.codec | 当需要将TEXTFILE数据文件以压缩方式写入OSS时,请添加该属性。 | TEXTFILE压缩属性。设置TEXTFILE数据文件的压缩方式。 说明:只支持 |
| 无 |
io.compression.codecs | 当OSS数据文件为Raw-Snappy格式时,请添加该属性。 | 配置该参数值为True时,MaxCompute才可以正常读取压缩数据,否则MaxCompute无法成功读取数据。 | com.aliyun.odps.io.compress.SnappyRawCodec | 无 |
写入数据
MaxCompute写入语法详情,请参见写入语法说明。
查询分析
Smart Parse更灵活的类型能力
针对CSV格式的OSS外部表,MaxCompute SQL采用2.0数据类型进行读写,之前仅支持部分严格格式的值,并按照相应的数据类型进行读写。现已兼容读取CSV中各种类型的值。具体如下:
Type | Input as String | Output as String | Description |
BOOLEAN |
说明 解析时会对输入执行 |
| 不在枚举值范围,则解析失败。 |
TINYINT |
说明
|
| 8位整型,超出值域范围 |
SMALLINT | 16位整型,超出值域范围 | ||
INT | 32位整型,超出值域范围 | ||
BIGINT | 64位整型,超出值域范围 说明
| ||
FLOAT |
说明
|
| 特殊值(大小写不敏感)包括:NaN、Inf、-Inf、Intifniy和-Intifniy。在超出值域范围时,将报错;若精度超出,则进行四舍五入截断。 |
DOUBLE |
说明
|
| 特殊值(大小写不敏感)包括:NaN、Inf、-Inf、Intifniy和-Intifniy。在超出值域范围时,将报错;若精度超出,则进行四舍五入截断。 |
DECIMAL (precision, scale) 以DECIMAL(15,2)为例 |
说明
|
| 整数部分值超出 则会报错;小数部分超出scale,则会进行四舍五入截断。 |
CHAR(n) 以CHAR(7)为例 |
|
| 最大长度为255。长度不足则会填充空格,但空格不参与比较。长度超出n会截断。 |
VARCHAR(n) 以VARCHAR(7)为例 |
|
| 最大长度为65535。长度超出n会截断。 |
STRING |
|
| 长度限制为8 MB。 |
DATE |
说明 您也可以通过自定义 |
|
|
TIMESTAMP_NTZ 说明 OpenCsvSerde不支持此类型,因为该类型与Hive数据格式不兼容。 |
|
|
|
DATETIME |
| 假设系统时区为Asia/Shanghai:
|
|
TIMESTAMP |
| (假设系统时区为Asia/Shanghai)
|
|
注意事项
对于任意类型,CSV数据文件中的空字符串被读入表中后,均会被解析为NULL。
不支持STRUCT/ARRAY/MAP等复杂类型,因为这些复杂类型的值很容易和CSV的常见分隔符(,)发生冲突导致解析失败。
暂不支持BINARY/INTERVAL类型,如有需求请联系MaxCompute技术支持。
对于数据类型INT/SMALLINT/TINYINT/BIGINT/FLOAT/DOUBLE/DECIMAL,默认的解析能力(DEFAULT)比较丰富。
如果您只想对基础的数字串进行解析,可以在
tblproperties
中将odps.text.option.smart.parse.level
参数设置为naive
,使解析器仅支持解析普通数字串,例如“123”、“123.456”,其他形态的字符串在解析时会报错。对于四种日期或时间相关类型DATA/DATATIME/TIMESTAMP/TIMESTAMP_NTZ,在底层代码中均使用
java.time.format.DateTimeFormatter
进行处理。MaxCompute内置了若干的默认解析格式,您也可以通过在tblproperties
中设置odps.text.option.<date|datetime|timestamp|timestamp_ntz>.io.format
来自定义多种解析格式与一种输出格式,解析格式之间用#
分隔。自定义格式的优先级高于MaxCompute的内置解析格式,输出格式将采用第一个自定义格式。
例如,若您自定义DATE类型的格式串为
pattern1#pattern2#pattern3
,则可以解析符合pattern1
、pattern2
或pattern3
的字符串,但输出至文件时会采用pattern1
格式来输出。详情请参见DateTimeFormatter。不建议使用 'z' (time-zone name) 作为自定义的时区格式(尤其对于中国区用户),因为 'z' 在某些上下文中可能存在歧义。
例如:'CST' 在中国语境下通常表示中国标准时间(UTC+8),然而当 'CST' 被
java.time.format.DateTimeFormatter
解析时,会被识别为美国中部标准时间(UTC-6),这可能导致非预期的输入或输出结果。建议您改用 'x' (zone-offset) 或 'VV' (time-zone ID) 作为时区模式。
使用示例
执行下述示例代码时,请将代码中的
<uid>
替换为您的阿里云账号ID。下述示例中使用的角色为
aliyunodpsdefaultrole
,如果您想使用其他角色,需要将aliyunodpsdefaultrole
替换为目标角色名称,并为目标角色授予访问OSS的权限。
通过内置文本数据解析器创建OSS外部表-非分区表
与示例数据中的
Demo1/
目录建立映射关系。创建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/'; -- 您可以执行desc extended mc_oss_csv_external1;命令查看创建好的OSS外部表结构信息。
查询非分区外表。
SELECT * FROM mc_oss_csv_external1;
返回结果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 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 | +------------+------------+------------+------------+------------------+-------------------+------------+----------------+
写入数据至非分区外表,并查看数据是否已成功写入。
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;
返回结果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 12 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | SW | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
查看OSS路径
Demo1/
下已产生新文件。
通过内置文本数据解析器创建OSS外部表-分区表
与示例数据中的
Demo2/
目录建立映射关系。创建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/'; --引入分区数据。 MSCK REPAIR TABLE mc_oss_csv_external2 ADD PARTITIONS; --等效于如下语句。 ALTER TABLE mc_oss_csv_external2 ADD PARTITION (direction = 'N') PARTITION (direction = 'NE') PARTITION (direction = 'S') PARTITION (direction = 'SW') PARTITION (direction = 'W'); -- 您可以执行DESC EXTENDED mc_oss_csv_external2;命令查看创建好的外部表结构信息。
查询分区外表。
SELECT * FROM mc_oss_csv_external2 WHERE direction='NE';
返回结果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 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 | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
写入数据至分区外表,并查看是否已成功写入。
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;
返回结果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 12 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | NE | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
查看OSS路径
Demo2/direction=NE
下已产生新文件。
通过内置文本数据解析器创建OSS外部表-压缩数据
本示例创建以GZIP压缩的CSV格式外表,进行数据读取和写入操作。
创建内部表并写入测试数据,用来进行后续的写入测试。
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');
创建以GZIP压缩的CSV格式外表,与示例数据中的
Demo3/
(压缩数据)目录建立映射关系。创建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/'; -- 引入分区数据 MSCK REPAIR TABLE mc_oss_csv_external3 ADD PARTITIONS; -- 您可以执行DESC EXTENDED mc_oss_csv_external3;命令查看创建好的外部表结构信息。
使用MaxCompute客户端,从OSS中读取数据。命令示例如下:
说明如果OSS压缩数据为开源数据格式,需要在SQL语句前添加
set odps.sql.hive.compatible=true;
命令,与SQL语句一起提交执行。--开启全表扫描,仅此Session有效。 SET odps.sql.allow.fullscan=true; SELECT recordId, patientId, direction FROM mc_oss_csv_external3 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 | +------------+------------+------------+
读取内部表的数据写入至OSS外表。
通过MaxCompute客户端对外部表执行
INSERT OVERWRITE
或INSERT INTO
命令,将数据写入OSS。INSERT INTO TABLE mc_oss_csv_external3 PARTITION (dt='20250418') SELECT * FROM vehicle_test;
执行成功后,您可在OSS目录下查看导出的文件。
创建OSS外部表并指定对应OSS文件的第一行为表头
在示例数据的oss-mc-test
Bucket下创建Demo11
目录,并执行如下语句:
--创建外部表
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'
)
LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo11/';
--插入数据
INSERT OVERWRITE TABLE mf_oss_wtt VALUES (1, 'val1', 1.1),(2, 'value2', 1.3);
--查询数据
--在建表的时候可以把所有字段建成string,否则表头读取时会报错。
--或者在建表的时候需要加跳过表头的参数:'odps.text.option.header.lines.count' = '1'
SELECT * FROM mf_oss_wtt;
返回结果如下:
+----------+--------+------------+
| id | name | tran_amt |
+----------+--------+------------+
| 1 | val1 | 1.1 |
| 2 | value2 | 1.3 |
+----------+--------+------------+
创建OSS外部表且外部表列数与OSS数据列数不一致
在示例数据的
oss-mc-test
Bucket下创建demo
目录,并上传test.csv
文件。test.csv
文件内容如下。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
创建外部表。
指定对于列数不一致的行的处理方式为
TRUNCATE
。--删除表 DROP TABLE test_mismatch; --新建外部表 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') LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/';
指定对于列数不一致的行的处理方式为
IGNORE
。--删除表 DROP TABLE test_mismatch01; --新建外部表 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/';
查询表数据。
查询test_mismatch表。
SELECT * FROM test_mismatch; --返回结果 +----+-------+---------------+---------------+ | 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 | +----+-------+---------------+---------------+
查询test_mismatch01表。
SELECT * FROM test_mismatch01; --返回结果 +----+-------+----------------+-------------+ | id | name | dect | col4 | +----+-------+----------------+-------------+ | 2 | kyle2 | this is desc2 | this is two +----+-------+----------------+-------------+
创建CSV格式的OSS外部表-自定义各种时间数据类型
CSV自定义时间类型的解析与输出格式详情,请参见Smart Parse更灵活的类型能力。
创建各时间数据类型的CSV外表(datetime/timestamp/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/' 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');
插入数据后,CSV文件的内容为:
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
再次读数据,可以看到结果。
SELECT * FROM test_csv;
返回结果如下:
+------------+---------------------+---------------------+------------------------+ | 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 | +------------+---------------------+---------------------+------------------------+