Афина не может разобрать дату с помощью OpenCSVSerde - PullRequest
0 голосов
/ 29 сентября 2018

У меня очень простой CSV-файл на S3

"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) Я получаю ошибку, подобную этой:

HIVE_BAD_DATA:
Ошибка анализа значения поля '2018-01-01' для поля 1: для входной строки: "2018-01-01 "

Дополнительная информация:

  • Если я изменю столбец d на строку, запрос будет выполнен успешно
  • У меня был ранеепроанализировал даты в текстовых файлах, используя Athena;Я считаю, что использование LazySimpleSerDe
  • Определенно кажется похоже на проблему с OpenCSVSerde

Документация определенно подразумевает, чтоэто поддерживается.Ищу всех, кто сталкивался с этим, или какие-либо предложения.

Ответы [ 2 ]

0 голосов
/ 28 июля 2019

На самом деле, это проблема с документацией , которую вы упомянули.Возможно, вы ссылались на этот отрывок:

[OpenCSVSerDe] распознает тип DATE, если он указан в формате UNIX, например, YYYY-MM-DD, как тип LONG.

Понятно, что вы форматировали дату как ГГГГ-ММ-ДД.Тем не менее, документация глубоко вводит в заблуждение в этом предложении.Когда он ссылается на формат UNIX, на самом деле он имеет в виду Время эпохи UNIX .

Исходя из определения эпохи UNIX, ваши даты должны быть целыми числами (поэтому ссылка на тип LONG вдокументация).Ваши даты должны быть числом дней, прошедших с 1 января 1970 года.

Например, ваш образец 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");

Если вы запросите таблицу Athena с помощью 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    

Аналогичная проблема также нарушает объяснение TIMESTAMP в вышеупомянутой документации:

[OpenCSVSerDe] распознает тип TIMESTAMP, если он указан в формате UNIX, например yyyy-mm-dd hh:mm:ss[.f...], как тип LONG.

Кажется, это указывает на то, что мыдолжен отформатировать TIMESTAMP как yyyy-mm-dd hh:mm:ss[.f...].На самом деле, нет.Фактически нам нужно снова использовать время эпохи UNIX, но на этот раз с количеством миллисекунд, прошедших с полуночи 1 января 1970 года.

Например, рассмотрим следующий образец 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  
0 голосов
/ 29 сентября 2018

Один из способов - объявить столбец d как строку, а затем в запросе выбора использовать DATE (d) или date_parse для анализа значения как типа данных date.

...