【问题标题】:Hive table from CSV. The line termination in quotes来自 CSV 的 Hive 表。引号中的行终止
【发布时间】:2018-02-13 09:41:47
【问题描述】:

我尝试从保存到 HDFS 的 CSV 文件创建表。问题是 csv 在引号内包含 换行符。 CSV 记录示例:

ID,PR_ID,SUMMARY
2063,1184,"This is problem field because consists line break

This is not new record but it is part of text of third column
"

我创建了配置单元表:

CREATE TEMPORARY EXTERNAL TABLE  hive_database.hive_table
(   
    ID STRING,
    PR_ID STRING,
    SUMMARY STRING 
)
row format serde 'com.bizo.hive.serde.csv.CSVSerde'
with serdeproperties (
    "separatorChar" = ",",
    "quoteChar"     = "\"",
    "escapeChar"  = "\""
)     
stored as textfile
LOCATION '/path/to/hdfs/dir/csv'
tblproperties('skip.header.line.count'='1');

然后我尝试计算行数(正确的结果应该是 1)

Select count(*) from hive_database.hive_table;

但结果是 4 不正确。你知道如何解决它吗?谢谢大家。

【问题讨论】:

    标签: hadoop hive opencsv


    【解决方案1】:

    我找到了解决方案。您可以定义自己的 InputFormatter。然后 HQL 表的 DDL 将如下所示(首先您需要添加自定义 jar 文件):

    ADD JAR /path/to/your/jar/CSVCustomInputFormat.jar;
    DROP TABLE hive_database.hive_table;
    CREATE EXTERNAL TABLE  hive_database.hive_table
    (   
        ID STRING,
        PR_ID STRING,
        SUMMARY STRING 
    )
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
    WITH SERDEPROPERTIES (
       "separatorChar" = ",",
       "quoteChar"     = "\"",
       "escapeChar"    = "\\"
    ) 
    STORED AS 
    INPUTFORMAT 'com.hql.custom.formatter.CSVCustomInputFormatt' 
    OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat' 
    LOCATION '/path/to/hdfs/dir/csv'
    tblproperties('skip.header.line.count'='1');
    

    然后如何创建自定义输入格式化程序,您可以在这里看到例如:https://analyticsanvil.wordpress.com/2016/03/06/creating-a-custom-hive-input-format-and-record-reader-to-read-fixed-format-flat-files/

    【讨论】:

    • 这是一个很好的资源。对我来说,一个关键的收获是:创建与 Hive 一起使用的自定义类时的一个关键区别如下: InputFormat 和 RecordReader - 将文件作为输入 - 生成行 SerDe - 将行作为输入 - 生成列
    【解决方案2】:

    目前没有办法直接处理 hive 中的多行 csv。 但是,有一些解决方法:

    1. 生成带有\n\r\n 的csv 替换为您自己的换行符,例如<\br>。您将能够将其加载到配置单元中。然后通过将后者替换为前者来转换结果文本

    2. 使用 spark,它有一个多行 csv 阅读器。这可以解决问题,而 csv 不是以分布式方式读取的。

      val df = spark.read
      .option("wholeFile", true)
      .option("multiline",true)
      .option("header", true)
      .option("inferSchema", "true")
      .option("dateFormat", "yyyy-MM-dd")
      .option("timestampFormat", "yyyy-MM-dd HH:mm:ss")
      .csv("test.csv")
      .write.format("orc")
      .saveAsTable("myschma.myTable")
      
    3. 使用其他格式,例如 parquet、avro、orc、序列文件,而不是 csv。例如,您可以使用 sqoop 从 jdbc 数据库生成它们。或者你可以用java或python编写你自己的程序。

    【讨论】:

    • 这节省了发言权。也适用于 gzip 文件和镶木地板
    猜你喜欢
    • 2016-01-20
    • 1970-01-01
    • 2017-01-29
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-15
    相关资源
    最近更新 更多