假设我想在Hive中创建一个包含4列的简单表,并从管道开始加载一些管道分隔的数据。
CREATE table TEST_1 (
COL1 string,
COL2 string,
COL3 string,
COL4 string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|';
原始数据:
|123|456|Dasani Bottled|5|,
|124|455|Test Bottled |7|
表格获取日期,如
----------------------------------
COL1 COL2 COL3 COL4
----------------------------------
123 456 Dasani Bottled
123 455 Test Bottled
----------------------------------
COL1为空,最后一列未加载。我尝试使用Hadoop put命令加载csv文件。
帮我解决这个问题。
如果修复数据文件不是一个选项,您可以使用RegexSerDe而不是LasySimpleSerDe(文本文件的默认SerDe(。
定义数据在正则表达式中的外观。每一列在正则表达式中都应该有相应的捕获组((。
要在创建表之前测试regex的工作方式,请使用regex_replace
select regexp_replace('|123|456|Dasani Bottled|5|, ', --your row example
'^\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|.*', --4 groups are in the regex
'$1 $2 $3 $4'); --output space delimited fields
结果:
123 456 Dasani Bottled 5
如果正则表达式按预期工作,请创建表(不一定是外部的(:
create external table TEST_1 (
COL1 string,
COL2 string,
COL3 string,
COL4 string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES ('input.regex'='^\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|.*')
location ....
;
然后将文件复制到表位置或使用LOAD命令。
您可以通过两种方法解决此问题。
- 在处理文件之前删除第一列。这是一种清洁且优选的解决方案
cut -d "|" -f 2- input_filename > output_filename
然后使用这个output_filname作为加载过程的输入。
-d "|"
——也就是说,使用管道作为分隔符。-f 2-
-这意味着,提取第一个字段之后的所有内容。
- 在表的开头添加一个伪列,如下所示
CREATE table TEST_1 (
dummy string,
COL1 string,
COL2 string,
COL3 string,
COL4 string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|';
然后继续加载数据。然后,您可以忽略此伪列,或者将数据存储到没有此列的最终表中,或者在此之上创建一个视图以排除此伪列。