用于处理 CSV 的 Open CSV SerDe
使用 Open CSV SerDe 库从逗号分隔(CSV)的数据创建 Athena 表。
序列化库名称
Open CSV SerDe 的序列化库名称是 org.apache.hadoop.hive.serde2.OpenCSVSerde
。有关源代码信息,请参阅 Apache 文档中的 CSV SerDe
使用 Open CSV SerDe
要使用此 SerDe,请在 ROW FORMAT
SERDE
后指定其完全限定类名。还需在 SERDEPROPERTIES
中指定分隔符,如以下示例所示。
... ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH SERDEPROPERTIES ( "separatorChar" = ",", "quoteChar" = "`", "escapeChar" = "\\" )
忽略标头
要在您定义表时忽略标题,可以使用 skip.header.line.count
表属性,如下例所示。
TBLPROPERTIES ("skip.header.line.count"="1")
有关示例,请参阅 查询 Amazon VPC 流日志 和 查询 Amazon CloudFront 日志 中的 CREATE TABLE
语句。
字符串数据的注意事项
Open CSV SerDe 具有以下字符串数据特性:
-
使用双引号 (
"
) 作为默认引号字符,还允许您指定分隔符、引号和转义符,例如:WITH SERDEPROPERTIES ("separatorChar" = ",", "quoteChar" = "`", "escapeChar" = "\\" )
-
\t
或\n
无法直接转义。要对它们进行转义,请使用"escapeChar" = "\\"
。有关示例,请参阅Example: Escaping \t or \n。 -
Open CSV SerDe 不支持 CSV 文件中的嵌入换行符。
非字符串数据的注意事项
对于不是 STRING
的数据类型,Open CSV SerDe 的行为如下所示:
-
识别
BOOLEAN
、BIGINT
、INT
和DOUBLE
数据类型。 -
在定义为数值数据类型的列中,无法识别空或空值,请将其保留为
string
。一种解决方法是创建带有空值为string
的列,然后使用CAST
将查询中的字段转换为数字数据类型,为空值提供0
的默认值。有关更多信息,请参阅 AWS 知识中心中的当我在 Athena 中查询 CSV 数据时,出现错误 HIVE_BAD_DATA:错误解析字段值。 -
对于使用
CREATE TABLE
语句中的timestamp
数据类型指定的列,如果它使用的以毫秒为单位指定的 UNIX 数字格式,例如1579059880000
,则识别TIMESTAMP
数据。有关示例,请参阅Example: Using the TIMESTAMP type and DATE type specified in the UNIX numeric format。-
Open CSV SerDe 不支持采用 JDBC 兼容
java.sql.Timestamp
格式的TIMESTAMP
,例如"YYYY-MM-DD HH:MM:SS.fffffffff"
(9 位小数精度)。
-
-
对于使用
CREATE TABLE
语句中的DATE
数据类型指定的列,如果值表示自 1970 年 1 月 1 日以来已过去的天数,则会将值识别为日期。例如,列中带有date
数据类型的值18276
在查询时渲染为2020-01-15
。在这种 UNIX 格式下,每天都被认为有 86,400 秒。-
Open CSV SerDe 不直接支持任何其他格式的
DATE
。要处理其他格式的时间戳数据,可以将列定义为string
,然后使用时间转换函数在SELECT
查询中返回所需的值。有关更多信息,请参阅 AWS 知识中心中的文章:当在 Amazon Athena 中查询表时,时间戳结果为空 。
-
-
要进一步将表中的列转换为所需的类型,您可以针对表创建视图,并使用
CAST
转换为所需的类型。
示例
例 示例:查询简单的 CSV 数据
以下示例假设您已将包含以下内容的 CSV 数据保存在位置 s3://amzn-s3-demo-bucket/mycsv/
:
"a1","a2","a3","a4"
"1","2","abc","def"
"a","a1","abc3","ab4"
使用 CREATE TABLE
语句根据数据创建 Athena 表。ROW FORMAT SERDE
之后引用 OpenCSVSerde
(注意小写字母“d”)并指定 WITH SERDEPROPERTIES
中的字符分隔符、引号字符和转义字符,如以下示例所示。
CREATE EXTERNAL TABLE myopencsvtable ( col1 string, col2 string, col3 string, col4 string ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH SERDEPROPERTIES ( 'separatorChar' = ',', 'quoteChar' = '"', 'escapeChar' = '\\' ) STORED AS TEXTFILE LOCATION 's3://amzn-s3-demo-bucket/mycsv/';
查询表中的所有值:
SELECT * FROM myopencsvtable;
查询将返回以下值:
col1 col2 col3 col4
-----------------------------
a1 a2 a3 a4
1 2 abc def
a a1 abc3 ab4
例 示例:使用以 UNIX 数字格式指定的 TIMESTAMP 类型和 DATE 类型
请考虑以下三列逗号分隔的数据。每列中的值都包含在双引号内。
"unixvalue creationdate 18276 creationdatetime 1579059880000","18276","1579059880000"
以下语句在 Athena 中根据指定的 Amazon S3 存储桶位置创建表。
CREATE EXTERNAL TABLE IF NOT EXISTS testtimestamp1( `profile_id` string, `creationdate` date, `creationdatetime` timestamp ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' LOCATION 's3://amzn-s3-demo-bucket'
接下来运行以下查询:
SELECT * FROM testtimestamp1
查询返回以下结果,同时显示日期和时间数据:
profile_id creationdate creationdatetime unixvalue creationdate 18276 creationdatetime 1579146280000 2020-01-15 2020-01-15 03:44:40.000
例 示例:针对 \t 或 \n 进行转义
请考虑使用以下测试数据:
" \\t\\t\\n 123 \\t\\t\\n ",abc " 456 ",xyz
以下语句在 Athena 中创建一个表,指定 "escapeChar" = "\\"
。
CREATE EXTERNAL TABLE test1 ( f1 string, s2 string) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH SERDEPROPERTIES ("separatorChar" = ",", "escapeChar" = "\\") LOCATION 's3://amzn-s3-demo-bucket/dataset/test1/'
接下来运行以下查询:
SELECT * FROM test1;
它会返回此结果,针对 \t
或 \n
正确进行转义:
f1 s2 \t\t\n 123 \t\t\n abc 456 xyz