用于处理 CSV 的 OpenCSVSerDe
当您为 CSV 数据创建 Athena 表时,请根据您的数据包含的值类型确定要使用的 SerDe:
-
如果数据包含使用双引号 (
") 括起的值,则可以使用 OpenCSV SerDe在 Athena 中将这些值反序列化。如果您的数据不包含使用双引号 ( ") 括起的值,则无需指定任何 SerDe。在此情况下,Athena 使用默认LazySimpleSerDe。有关信息,请参阅 用于 CSV、TSV 和自定义分隔文件的 LazySimpleSerDe。 -
如果您的数据具有 UNIX 数字
TIMESTAMP值(例如,1579059880000),请使用 OpenCSVSerDe。如果您的数据使用java.sql.Timestamp格式,请使用 LazySimpleSerDe。
CSV SerDe (OpenCSVSerDe)
OpenCSV SerDe
-
使用双引号 (
") 作为默认引号字符,还允许您指定分隔符、引号和转义符,例如:WITH SERDEPROPERTIES ("separatorChar" = ",", "quoteChar" = "`", "escapeChar" = "\\" ) -
\t或\n无法直接转义。要对它们进行转义,请使用"escapeChar" = "\\"。请参阅本主题中的示例。 -
不支持 CSV 文件中的嵌入换行符。
对于不是 STRING 的数据类型,OpenCSVSerDe 的行为如下所示:
-
识别
BOOLEAN、BIGINT、INT和DOUBLE数据类型。 -
在定义为数值数据类型的列中,无法识别空或空值,请将其保留为
string。一种解决方法是创建带有空值为string的列,然后使用CAST将查询中的字段转换为数字数据类型,为空值提供0的默认值。有关更多信息,请参阅 Amazon 知识中心中的当我在 Athena 中查询 CSV 数据时,出现错误 HIVE_BAD_DATA:错误解析字段值。 -
对于使用
CREATE TABLE语句中的timestamp数据类型指定的列,如果它使用的以毫秒为单位指定的 UNIX 数字格式,例如1579059880000,则识别TIMESTAMP数据。-
OpenCSVSerDe 不支持采用 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 秒。-
OpenCSVSerDe 不直接支持任何其他格式的
DATE。要处理其他格式的时间戳数据,可以将列定义为string,然后使用时间转换函数在SELECT查询中返回所需的值。有关更多信息,请参阅 Amazon 知识中心中的文章:当在 Amazon Athena 中查询表时,时间戳结果为空 。
-
-
要进一步将表中的列转换为所需的类型,您可以针对表创建视图,并使用
CAST转换为所需的类型。
例 示例:使用以 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://DOC-EXAMPLE-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://DOC-EXAMPLE-BUCKET/dataset/test1/'
接下来运行以下查询:
SELECT * FROM test1;
它会返回此结果,针对 \t 或 \n 正确进行转义:
f1 s2 \t\t\n 123 \t\t\n abc 456 xyz
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 语句。
示例
此示例假定 CSV 中的数据保存在 s3:// 中且具有以下内容:DOC-EXAMPLE-BUCKET/mycsv/
"a1","a2","a3","a4"
"1","2","abc","def"
"a","a1","abc3","ab4"
使用 CREATE TABLE 语句根据数据创建 Athena 表。ROW FORMAT SERDE 之后应用 OpenCSVSerDe 类并指定 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://DOC-EXAMPLE-BUCKET/mycsv/';
查询表中的所有值:
SELECT * FROM myopencsvtable;
查询将返回以下值:
col1 col2 col3 col4
-----------------------------
a1 a2 a3 a4
1 2 abc def
a a1 abc3 ab4