雅典娜无法使用opencsvserde解析日期

z9gpfhce  于 2021-06-25  发布在  Hive
关注(0)|答案(2)|浏览(450)

我在s3上有一个非常简单的csv文件

"i","d","f","s"
"1","2018-01-01","1.001","something great!"
"2","2018-01-02","2.002","something terrible!"
"3","2018-01-03","3.003","I'm an oil man"

我正在尝试使用以下命令创建一个跨此表的表

CREATE EXTERNAL TABLE test (i int, d date, f  float, s string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' 
LOCATION 's3://mybucket/test/'
TBLPROPERTIES ("skip.header.line.count"="1");

当我查询表时( select * from test )我得到了这样一个错误:
配置单元错误数据:
分析字段1的字段值“2018-01-01”时出错:对于输入字符串:“2018-01-01”
更多信息:
如果我改变主意 d 列转换为字符串,查询将成功
我以前用雅典娜解析过文本文件中的日期;我相信使用lazysimpleserde
显然opencsvserde有问题
文档明确地暗示这是支持的。寻找任何人谁遇到了这个,或任何建议。

fumotvh3

fumotvh31#

事实上,你提到的文档有问题。你可能指的是这段摘录:
[opencsvserde]识别以unix(如yyyy-mm-dd)指定为long类型的日期类型。
可以理解的是,您将日期格式化为yyyy-mm-dd。但是,文档中的这句话具有严重的误导性。当它提到unix时,实际上它考虑了unix纪元时间。
根据unix epoch的定义,日期应该是整数(因此文档中对long类型的引用)。您的日期应该是自1970年1月1日以来经过的天数。
例如,您的示例csv应该如下所示:

"i","d","f","s"
"1","17532","1.001","something great!"
"2","17533","2.002","something terrible!"
"3","17534","3.003","I'm an oil man"

然后可以运行完全相同的命令:

CREATE EXTERNAL TABLE test (i int, d date, f  float, s string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' 
LOCATION 's3://mybucket/test/'
TBLPROPERTIES ("skip.header.line.count"="1");

如果你用 select * from test ,您将获得:

i       d          f              s           
 --- ------------ ------- --------------------- 
  1   2018-01-01   1.001   something great!     
  2   2018-01-02   2.002   something terrible!  
  3   2018-01-03   3.003   I'm an oil man

类似的问题也影响了上述文档中关于时间戳的解释:
[opencsvserde]识别时间戳类型,如果它是以unix指定的,例如 yyyy-mm-dd hh:mm:ss[.f...] ,因为类型很长。
这似乎表明我们应该将时间戳格式化为 yyyy-mm-dd hh:mm:ss[.f...] . 不是真的。事实上,我们需要再次使用unix epoch时间,但这次使用的是自1970年1月1日午夜以来经过的毫秒数。
例如,考虑以下示例csv:

"i","d","f","s","t"
"1","17532","1.001","something great!","1564286638027"
"2","17533","2.002","something terrible!","1564486638027"
"3","17534","3.003","I'm an oil man","1563486638012"

以及以下create table语句:

CREATE EXTERNAL TABLE test (i int, d date, f  float, s string, t timestamp)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' 
LOCATION 's3://mybucket/test/'
TBLPROPERTIES ("skip.header.line.count"="1");

这将是的结果集 select * from test :

i       d          f              s                       t             
 --- ------------ ------- --------------------- ------------------------- 
  1   2018-01-01   1.001   something great!      2019-07-28 04:03:58.027  
  2   2018-01-02   2.002   something terrible!   2019-07-30 11:37:18.027  
  3   2018-01-03   3.003   I'm an oil man        2019-07-18 21:50:38.012
xtfmy6hx

xtfmy6hx2#

一种方法是将d列声明为string,然后在select查询中使用date(d)或date\u parse将值解析为date数据类型。

相关问题