【问题标题】:Load data into Hive with custom delimiter使用自定义分隔符将数据加载到 Hive
【发布时间】:2016-12-13 23:56:01
【问题描述】:

我正在尝试在 hive 中创建一个内部(托管)表来存储我的增量日志数据。表格是这样的:

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; 我明白了,

120  =>abcdefg  NULL

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

任何人都可以就如何提供自定义分隔符和成功加载数据提供帮助。

【问题讨论】:

  • 是终结符还是分隔符?
  • 多个字段之间的分隔符。正如在创建查询“ROW FORMAT DELIMITED FIELDS TERMINATED BY ''”中提到的那样

标签: hadoop hive loaddata bigdata


【解决方案1】:

默认情况下,hive 只允许用户使用单个字符作为字段分隔符。虽然有 RegexSerDe 来指定多字符分隔符,但使用起来可能会让人望而生畏,尤其是对于业余爱好者而言。

补丁 (HIVE-5871) 添加了一个名为 MultiDelimitSerDe 的新 SerDe。使用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> 

【讨论】:

  • 感谢您的快速响应,它成功了,现在我可以加载数据了。但是当我执行select * 以外的查询时,我得到Class org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe not found 异常。那么,您可以指定来源和添加位置吗?
  • 您需要获取更新的 jar 并将其放在 $HIVE_HOME/lib 目录中...请参阅我的答案中的 Jira 票证,其中详细说明了此类可用的版本(hive 0.14 及更高版本)@ 987654322@
【解决方案2】:
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;

【讨论】:

    【解决方案3】:

    我建议您使用前面提到的 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
    

    【讨论】:

      猜你喜欢
      • 2014-10-25
      • 1970-01-01
      • 1970-01-01
      • 2021-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-07
      • 1970-01-01
      相关资源
      最近更新 更多