如何在使用 EMR/Hive 将数据从 S3 导入 DynamoDB 时处理包含在引号 (CSV) 中的字段
Posted
技术标签:
【中文标题】如何在使用 EMR/Hive 将数据从 S3 导入 DynamoDB 时处理包含在引号 (CSV) 中的字段【英文标题】:How to handle fields enclosed within quotes(CSV) in importing data from S3 into DynamoDB using EMR/Hive 【发布时间】:2012-12-13 05:51:24 【问题描述】:我正在尝试使用 EMR/Hive 将数据从 S3 导入 DynamoDB。我的 CSV 文件包含用双引号括起来并用逗号分隔的字段。 在 hive 中创建外部表时,我可以将分隔符指定为逗号,但如何指定字段用引号括起来?
如果我不指定,我会看到 DynamoDB 中的值填充在两个双引号“值”中,这似乎是错误的。
我正在使用以下命令来创建外部表。有没有办法指定字段用双引号括起来?
CREATE EXTERNAL TABLE emrS3_import_1(col1 string, col2 string, col3 string, col4 string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '","' LOCATION 's3://emrTest/folder';
任何建议将不胜感激。 谢谢 日腾德拉
【问题讨论】:
【参考方案1】:我也遇到了同样的问题,因为我的字段用双引号括起来并用分号 (;) 分隔。我的表名是employee1。
所以我搜索了链接,并找到了完美的解决方案。
为此,我们必须使用 serde。请使用此链接下载 serde jar:https://github.com/downloads/IllyaYalovyy/csv-serde/csv-serde-0.9.1.jar
然后使用 hive 提示执行以下步骤:
add jar path/to/csv-serde.jar;
create table employee1(id string, name string, addr string)
row format serde 'com.bizo.hive.serde.csv.CSVSerde'
with serdeproperties(
"separatorChar" = "\;",
"quoteChar" = "\"")
stored as textfile
;
然后使用以下查询从给定路径加载数据:
load data local inpath 'path/xyz.csv' into table employee1;
然后运行:
select * from employee1;
现在您将看到魔法。谢谢。
【讨论】:
我认为这应该是“正确”的答案。任何人?只是一件事,如果您的代码没有运行,请将“\””更改为“\”'。 万一有人再次遇到这个问题。 Hive 现在包括开箱即用的org.apache.hadoop.hive.serde2.OpenCSVSerde
。请参阅下面的答案。【参考方案2】:
以下代码解决了相同类型的问题
CREATE TABLE TableRowCSV2(
CODE STRING,
PRODUCTCODE STRING,
PRICE STRING
)
COMMENT 'row data csv'
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
"separatorChar" = "\,",
"quoteChar" = "\""
)
STORED AS TEXTFILE
tblproperties("skip.header.line.count"="1");
【讨论】:
【参考方案3】:如果您无法使用 CSV 文件格式,则必须使用自定义 SerDe;这是一些work based on the opencsv libarary。
但是,如果您可以修改源文件,您可以选择一个新的分隔符,这样引用的字段就不需要了(祝您好运),或者重写以使用单个转义字符转义任何嵌入的逗号,例如'\',可以在 ROW FORMAT 中用 ESCAPED BY 指定:
CREATE EXTERNAL TABLE emrS3_import_1(col1 string, col2 string, col3 string, col4 string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ESCAPED BY '\\' LOCATION 's3://emrTest/folder';
【讨论】:
【参考方案4】:Hive 现在包含一个 OpenCSVSerde
,它将正确解析那些引用的字段,而无需添加额外的 jar 或容易出错且速度较慢的正则表达式。
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
【讨论】:
【参考方案5】:Hive 不支持开箱即用的带引号的字符串。有两种方法可以解决这个问题:
-
使用不同的字段分隔符(例如管道)。
基于 OpenCSV 编写自定义 InputFormat。
更快(并且可以说更理智)的方法是修改您的初始导出过程以使用不同的分隔符,这样您就可以避免引用字符串。通过这种方式,您可以告诉 Hive 使用带有制表符或管道分隔符的外部表:
CREATE TABLE foo (
col1 INT,
col2 STRING
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '|';
【讨论】:
【参考方案6】:在您的 Hive 查询中使用 csv-serde-0.9.1.jar
文件,请参阅
http://illyayalovyy.github.io/csv-serde/
add jar /path/to/jar_file
Create external table emrS3_import_1(col1 string, col2 string, col3 string, col4 string) row format serde 'com.bizo.hive.serde.csv.CSVSerde'
with serdeproperties
(
"separatorChar" = "\;",
"quoteChar" = "\"
) stored as textfile
tblproperties("skip.header.line.count"="1") ---to skip if have any header file
LOCATION 's3://emrTest/folder';
【讨论】:
【参考方案7】:这个问题可以有多种解决方案。
-
编写自定义 SerDe 类
使用 RegexSerde
从数据中删除转义的分隔符
阅读更多http://grokbase.com/t/hive/user/117t2c6zhe/urgent-hive-not-respecting-escaped-delimiter-characters
【讨论】:
以上是关于如何在使用 EMR/Hive 将数据从 S3 导入 DynamoDB 时处理包含在引号 (CSV) 中的字段的主要内容,如果未能解决你的问题,请参考以下文章
如何从 NodeJS 和 Lambda 在 EMR Hive 上运行查询
如何将镶木地板文件从 s3 导入到 postgresql rds