【发布时间】:2016-09-30 17:16:01
【问题描述】:
我有一个 CSV 文件,我正在尝试将其导入 Amazon DynamoDB。所以我把它上传到 S3,建立一个 EMR 集群,然后创建一个像这样的外部表:
hive> CREATE EXTERNAL TABLE s3_table_myitems (colA BIGINT, colB STRING, colC STRING, colD DOUBLE, colE DOUBLE, colF STRING, colG STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES ('serialization.null.format'='""')
STORED AS TEXTFILE
LOCATION 's3://bucketname/dirname/'
TBLPROPERTIES ('skip.header.line.count'='1');
CSV 中的任何列都可能为空,但 DynamoDB 无法处理空字符串 ("com.amazonaws.AmazonServiceException: One or more parameter values were invalid: An AttributeValue may not contain an empty string")。
这就是Amazon says:
我们将考虑这个可选的“忽略空字符串”行为 未来的版本。 ... 作为一种解决方法,您可以... 转换为空 属性值转换为 NULL。例如,您可以……使用更复杂的 SELECT 表达式将空字符串转换为其他内容,包括 将它们设置为 NULL。
所以这就是我想出的,但它看起来很丑:
hive> INSERT INTO TABLE ddb_tbl_ingredients
SELECT
regexp_replace(colA, '^$', 'NULL'),
regexp_replace(colB, '^$', 'NULL'),
regexp_replace(colC, '^$', 'NULL'),
regexp_replace(colD, '^$', 'NULL'),
regexp_replace(colE, '^$', 'NULL'),
regexp_replace(colF, '^$', 'NULL'),
regexp_replace(colG, '^$', 'NULL')
FROM s3_table_ingredients;
对于整体问题是否有更好的解决方案(缺少对 CSV 的预处理),或者至少有更好的SELECT 语法?
编辑:我最终也不得不处理重复项(“com.amazonaws.AmazonServiceException: Provided list of item keys contains duplicates”)。
为了后代,这是我的完整流程。我很想听到更好的方法来做到这一点,无论是为了美观还是为了性能。任务看似简单(“将 CSV 文件导入 DynamoDB”),但到目前为止已经花费了几个小时:P
# source
hive> CREATE EXTERNAL TABLE s3_table_myitems (colA STRING, colB STRING, colC DOUBLE, colD DOUBLE, colE STRING, colF STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES ('serialization.null.format'='""')
STORED AS TEXTFILE
LOCATION 's3://bucketname/dirname/'
TBLPROPERTIES ('skip.header.line.count'='1');
# destination
hive> CREATE EXTERNAL TABLE ddb_tbl_myitems (colA STRING, colB STRING, colC DOUBLE, colD DOUBLE, colE STRING, colF STRING)
STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
TBLPROPERTIES ("dynamodb.table.name" = "myitems",
"dynamodb.column.mapping" = "colA:colA,colB:colB,colC:colC,colD:colD,colE:colE,colF:colF");
# remove dupes - http://stackoverflow.com/a/34165762/594211
hive> CREATE TABLE tbl_myitems_deduped AS
SELECT colA, min(colB) AS colB, min(colC) AS colC, min(colD) AS colD, min(colE) AS colE, min(colF) AS colF
FROM (SELECT colA, colB, colC, colD, unit, colF, rank() OVER
(PARTITION BY colA ORDER BY colB, colC, colD, colE, colF)
AS col_rank FROM s3_table_myitems) t
WHERE t.col_rank = 1
GROUP BY colA;
# replace empty strings with placeholder 'NULL'
hive> CREATE TABLE tbl_myitems_noempty AS
SELECT colA,
regexp_replace(colB, '^$', 'NULL') AS colB,
regexp_replace(colC, '^$', 'NULL') AS colC,
regexp_replace(colD, '^$', 'NULL') AS colD,
regexp_replace(colE, '^$', 'NULL') AS colE,
regexp_replace(colF, '^$', 'NULL') AS colF
FROM tbl_myitems_deduped
WHERE LENGTH(colA) > 0;
# ...other preprocessing here...
# insert to DB
hive> INSERT INTO TABLE ddb_tbl_myitems
SELECT * FROM tbl_myitems_noempty;
注意:colA 是分区键。
【问题讨论】:
-
我遇到了同样的问题。我解决了重复数据删除略有不同,但现在面临空字符串问题。我已经尝试过在 OpenCSVSerde 的 SerDe 属性以及 TBLPROPERTIES 中使用:
'serialization.null.format'='""',就像迄今为止唯一答案中提到的那样。
标签: csv hadoop amazon-web-services hive amazon-dynamodb