将CSV数据文件中的数组字段加载到Athena表中

时间:2018-06-25 11:11:31

标签: amazon-web-services amazon-athena

这是输入数据文件中的示例行,具有两个字段-部门和名称

dept,names
Mathematics,[foo,bar,alice,bob]

在这里,“名称”是一个String数组,我想将其作为String Athena数组加载。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

要获得有效的CSV文件,请确保在数组周围加上引号:

Mathematics,"[foo,bar,alice,bob]"

如果您可以删除“ [”和“]”,则下面的解决方案将变得更加容易,并且您可以不使用正则表达式进行拆分。

Better: Mathematics,"foo,bar,alice,bob"

首先使用仅包含字符串的CSV文件创建一个简单表:

CREATE EXTERNAL TABLE IF NOT EXISTS test.mydataset (
  `dept` string,
  `names` string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
  'serialization.format' = ',',
  'field.delim' = ',',
  'quoteChar' = '"',
  "separatorChar" = ',',
  'collection.delim' = ',',
  'mapkey.delim' = ':'
) LOCATION 's3://<your location>'
TBLPROPERTIES ('has_encrypted_data'='false')

然后创建一个使用正则表达式删除“ [”和“]”字符的视图,然后将其余部分按“,”分割成一个数组。

CREATE OR REPLACE VIEW mydataview AS
SELECT  dept, 
        split(regexp_extract(names, '^\[(.*)\]$', 1), ',') as names
FROM mydataset 

然后使用该视图进行查询。我不确定100%,因为我只花了12个小时就使用了雅典娜。

-

请注意,要使用引号,您需要使用OpenCSVSerde,“ lazyserde”将不起作用,因为它支持引号。 lazyserde DOES支持内部数组,但是在这种情况下,不能使用','作为分隔符。如果您想尝试一下,您的数据将如下所示:

Better: Mathematics,foo|bar|alice|bob

在这种情况下,此MIGHT可以直接工作:

CREATE EXTERNAL TABLE IF NOT EXISTS test.mydataset (
      `dept` string,
      `names` array<string>
    )
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
    WITH SERDEPROPERTIES (
      'serialization.format' = ',',
      'field.delim' = ',',
      'quoteChar' = '"',
      "separatorChar" = ',',
      'collection.delim' = '|',
      'mapkey.delim' = ':'
    ) LOCATION 's3://<your location>'
    TBLPROPERTIES ('has_encrypted_data'='false')

请注意collection.delim ='|'的方式,它将字段直接转换为数组。

对不起,我没有时间进行测试,如果您可以确认有效的方法,我将很乐意更新我的答案。希望这可以帮助您开始。