配置单元-从管道开始加载管道分隔的数据



假设我想在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命令。

您可以通过两种方法解决此问题。

  1. 在处理文件之前删除第一列。这是一种清洁且优选的解决方案
cut -d "|" -f 2- input_filename > output_filename

然后使用这个output_filname作为加载过程的输入。

-d "|"——也就是说,使用管道作为分隔符。-f 2--这意味着,提取第一个字段之后的所有内容。

  1. 在表的开头添加一个伪列,如下所示
CREATE table TEST_1 (
dummy string,
COL1  string,
COL2  string,
COL3  string,
COL4  string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|';

然后继续加载数据。然后,您可以忽略此伪列,或者将数据存储到没有此列的最终表中,或者在此之上创建一个视图以排除此伪列。

最新更新