如何将带有NULL值的引用CSV读入Amazon Athena

时间:2018-06-06 15:17:27

标签: amazon-athena

我正在尝试使用存储在S3上的引用CSV文件在Athena中创建外部表。问题是,我的CSV包含应该作为INT读取的列中的缺失值。简单的例子:

CSV:

id,height,age,name
1,,26,"Adam"
2,178,28,"Robert"

CREATE TABLE DEFINITION:

CREATE EXTERNAL TABLE schema.test_null_unquoted (
  id INT,
  height INT,
  age INT,
  name STRING
)
ROW FORMAT 
SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
'separatorChar' = ",",
'quoteChar' = '"',
'skip.header.line.count' = '1'
)
STORED AS TEXTFILE
LOCATION 's3://mybucket/test_null/unquoted/'

CREATE TABLE语句运行正常,但只要我尝试查询表格,我就会HIVE_BAD_DATA: Error parsing field value ''

我尝试使CSV看起来像这样(引用空字符串):

"id","height","age","name"
1,"",26,"Adam"
2,178,28,"Robert"

但它不起作用。

尝试在'serialization.null.format' = ''中指定SERDEPROPERTIES - 无效。

尝试通过TBLPROPERTIES ('serialization.null.format'='')指定相同内容 - 仍然没有。

当您将所有列指定为STRING时,它会起作用,但这不是我需要的。

因此,问题是,是否有以任何方式来读取引用的CSV(引用很重要,因为我的真实数据要复杂得多)到Athena并且列规范正确吗?

2 个答案:

答案 0 :(得分:3)

处理这些数据的快速而肮脏的方式:

CSV:

id,height,age,name
1,,26,"Adam"
2,178,28,"Robert"
3,123,34,"Bill, Comma"
4,183,38,"Alex"

DDL:

CREATE EXTERNAL TABLE stackoverflow.test_null_unquoted (
  id INT,
  height INT,
  age INT,
  name STRING
)
ROW FORMAT DELIMITED
 FIELDS TERMINATED BY ','
 LINES TERMINATED BY '\n' -- Or use Windows Line Endings
LOCATION 's3://XXXXXXXXXXXXX/'
TBLPROPERTIES ('skip.header.line.count'='1')
;

问题是它没有处理最后一个字段中的引号字符。基于AWS提供的文档,这是有道理的,因为LazySimpleSerDe从Hive给出以下内容。

我怀疑该解决方案正在使用以下SerDe org.apache.hadoop.hive.serde2.RegexSerDe

我稍后会处理正则表达式。

修改

正如所承诺的正则表达式:

CREATE EXTERNAL TABLE stackoverflow.test_null_unquoted (
  id INT,
  height INT,
  age INT,
  name STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "(.*),(.*),(.*),\"(.*)\""
)
LOCATION 's3://XXXXXXXXXXXXXXX/'
TBLPROPERTIES ('skip.header.line.count'='1') -- Does not appear to work
;

enter image description here

注意:RegexSerDe似乎与TBLPROPERTIES ('skip.header.line.count'='1')无法正常工作。这可能是由于雅典娜或塞尔德使用的Hive version。在您的情况下,您可能只会排除ID IS NULL的行。

进一步阅读:

Stackoverflow - remove surrounding quotes from fields while loading data into hive

Athena - OpenCSVSerDe for Processing CSV

答案 1 :(得分:0)

不幸的是,在 Athena 中无法同时获得对引用字段的支持对空值的支持。您必须选择或。

您可以使用 OpenCSVSerDe 并将所有列输入为字符串,这将为您提供对带引号的字段和空字段的 emtpty 字符串的支持。在查询时使用 TRY_CASTCASE/WHEN 转换值。

或者您可以使用 LazySimpleSerDe 并在查询时去除引号。

我会选择 OpenCSVSerDe,因为您始终可以创建包含所有类型转换的视图,并将该视图用于常规查询。

您可以在此处阅读在 Athena 中使用 CSV 的所有细节:The Athena Guide: Working with CSV