使用自定义分隔符将数据加载到Hive中

时间:2016-08-08 09:12:27

标签: hadoop hive loaddata bigdata

我正在尝试在hive中创建一个可以存储增量日志数据的内部(托管)表。表格如下:

TFrame

我需要定期将数据加载到此表中。

CREATE TABLE logs (foo INT, bar STRING, created_date TIMESTAMP)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '<=>'
STORED AS TEXTFILE;

但数据没有正确插入表中。分隔符可能存在一些问题。无法找到原因。

示例日志行:

LOAD DATA INPATH '/user/foo/data/logs' INTO TABLE logs;

120<=>abcdefg<=>2016-01-01 12:14:11

select * from logs;

第一个属性没问题,第二个属性包含分隔符的一部分但是因为它的字符串被插入而第三个将是null,因为它需要日期时间。

任何人都可以请求如何提供自定义分隔符并成功加载数据。

3 个答案:

答案 0 :(得分:1)

默认情况下,hive仅允许用户将单个字符用作字段分隔符。尽管RegexSerDe指定了多字符分隔符,但使用它可能会令人生畏,尤其是对业余爱好者而言。

补丁(HIVE-5871)添加了一个名为SerDe的新MultiDelimitSerDe。使用MultiDelimitSerDe时, 用户可以在创建表格时指定多字符字段分隔符 ,其方式与典型的表格创建方式最相似。

hive> CREATE TABLE logs (foo INT, bar STRING, created_date TIMESTAMP)
    > ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe' 
    > WITH SERDEPROPERTIES ("field.delim"="<=>")
    > STORED AS TEXTFILE;

hive> dfs -put /home/user1/multi_char.txt /user/hive/warehouse/logs/. ;

hive> select * from logs;
OK
120 abcdefg 2016-01-01 12:14:11
Time taken: 1.657 seconds, Fetched: 1 row(s)
hive> 

答案 1 :(得分:1)

CREATE TABLE logs (foo INT, bar STRING, created_date TIMESTAMP)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe'
WITH SERDEPROPERTIES (
    "field.delim"="<=>",
    "collection.delim"=":",
    "mapkey.delim"="@"
);

在表格中加载数据

load data local inpath '/home/kishore/Data/input.txt' overwrite into table logs;

答案 2 :(得分:1)

我建议你使用前面提到的 MultiDelimitSerDe 答案。您也可以试试 RegexSerDe 。但是你需要额外的步骤将它解析为你的数据类型,因为RegexSerde默认接受String。

RegexSerDe 可以方便地处理一些日志文件,其中的数据不是统一排列的,只有一个分隔符。

CREATE TABLE logs_tmp  (foo STRING,bar STRING, created_date STRING) 
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' 
WITH SERDEPROPERTIES (
 "input.regex" = "(\\d{3})<=>(\\w+)<=>(\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2})"
) 
STORED AS TEXTFILE;

LOAD DATA LOCAL INPATH 'logs.txt' overwrite into table logs_tmp;

CREATE TABLE logs  (foo INT,bar STRING, created_date TIMESTAMP) ;

INSERT INTO TABLE logs SELECT cast(foo as int) as foo,bar,cast(created_date as TIMESTAMP) as created_date from logs_tmp 

输出:

   OK
    Time taken: 0.213 seconds    
    hive> select * from logs;
    120     abcdefg 2016-01-01 12:14:11