使用默认SerDE加载Hive表数据

时间:2015-01-20 15:54:40

标签: hadoop hive

数据采用以下格式

a," b,c",d,e

p,q," e,r",t

a,s," t,g",t

我想创建一个Hive表

Col1,Col2,Col3,Col4

a,b,c,d,e

p,q,e,r,t

a,s,t,g,t

如上所述,如果数据封装在双引号中,则在创建表数据时不应考虑其间的逗号。如果我使用默认的SerDe,则忽略双引号,b,c被视为两个单独的列。

如果用双引号括起来,我如何确保双引号将忽略两个元素之间的逗号

2 个答案:

答案 0 :(得分:3)

如果可行且可行,我首先建议您探索是否可以使用除逗号以外的字符分隔符之类的方式对输入数据进行清理。使用可能在您的数据中自然出现的分隔模式总是很冒险。

但是,如果那是不可能的,那么有这种基于正则表达式的方法来检测引用的逗号:

  1. 首先将数据作为单列行(每行的整行)接收到临时表中。
  2. 检测引号之间出现的逗号,并用人工占位符替换它们。
  3. 使用逗号分隔结果字符串作为分隔符。
  4. 用他们最初代表的逗号替换人工占位符。
  5. 作为一个人为的具体例子,我用你的数据加载了以下单列临时表(步骤#1):

    hive> DESCRIBE staging;
    OK
    rawline                     string
    Time taken: 0.238 seconds, Fetched: 1 row(s)
    hive> SELECT * FROM staging;
    OK
    a,"b,c",d, e
    p,q,"e,r", t
    a,s,"t,g", t
    Time taken: 0.277 seconds, Fetched: 3 row(s)
    

    然后,以下查询将生成最终目标表。

    DROP TABLE IF EXISTS test;
    CREATE TABLE test (
        Col1 STRING,
        Col2 STRING,
        Col3 STRING,
        Col4 STRING
      );
    INSERT INTO TABLE test SELECT
      regexp_replace(fields[0], "\\[QUOTEDCOMMA\\]", ","),  -- Step #4
      regexp_replace(fields[1], "\\[QUOTEDCOMMA\\]", ","),  -- Step #4
      regexp_replace(fields[2], "\\[QUOTEDCOMMA\\]", ","),  -- Step #4
      regexp_replace(fields[3], "\\[QUOTEDCOMMA\\]", ",")   -- Step #4
    FROM (
      SELECT split(  -- Step #2 and #3
        regexp_replace(rawline, "\"([^,]*),([^,]*)\"", "$1[QUOTEDCOMMA]$2"),
        ',') AS fields
      FROM staging
    ) t;
    

    这将生成以下最终表test

    hive> SELECT * FROM test;
    OK
    a   b,c     d        e
    p   q       e,r      t
    a   s       t,g      t
    Time taken: 0.196 seconds, Fetched: 3 row(s)
    

    在此示例实现中,字符串[QUOTEDCOMMA]被用作引号之间的逗号的人工占位符。选择是完全随意的,在实践中,如果你走这条路线,你需要确保你的占位符不会自然地出现在你的数据中。

答案 1 :(得分:0)

Hive(LazySimple)中的默认文本serde不支持正确的CSV语义。好消息是,在迄今为止最新版本的蜂巢中 - 0.14.0 - 有一个新的服务员正在处理这个问题。如果您碰巧使用此版本,则可以使用CSV serde并指定双引号作为引号字符 - 从而导致正确解析数据,如您在问题中指定的那样。

有关serde以及如何使用它的信息: https://cwiki.apache.org/confluence/display/Hive/CSV+Serde

相关问题