2

増分ログ データを格納できる内部 (マネージド) テーブルをハイブに作成しようとしています。表は次のようになります。

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

最初の属性は問題ありません。2 番目の属性には区切り文字の一部が含まれていますが、挿入されるのは文字列であるため、3 番目の属性は日時を想定しているため null になります。

カスタム区切り文字を提供してデータを正常にロードする方法について、誰でも助けてください。

4

3 に答える 3

3

デフォルトでは、Hive は、ユーザーがフィールド区切り文字として 1 文字のみを使用できるようにします。複数文字の区切り文字を指定する RegexSerDe がありますが、特にアマチュアにとっては、使用するのが困難な場合があります。

パッチ ( HIVE-5871SerDe ) は、新しい名前付きを追加し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> 
于 2016-08-08T12:28:38.600 に答える
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;
于 2016-08-08T12:34:08.253 に答える
1

I suggest you to go with MultiDelimitSerDe answers mentioned earlier over mine. You can also give a try with RegexSerDe. But You need to have an additional step of parsing it to your datatypes since RegexSerde accepts String by default.

RegexSerDe will come to handy dealing with some log files where the data that is not uniformly arranged with only one single delimiter.

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 

output:

   OK
    Time taken: 0.213 seconds    
    hive> select * from logs;
    120     abcdefg 2016-01-01 12:14:11
于 2016-08-08T15:55:26.703 に答える