Skip to content

CSV文件字段存在换行符,如何正常读写存储到hive表? #6

Description

@bebee4java

csv文件某些文本字段里存在换行符,如:

id,name,desc
1,spark,"spark是一个分布式计算框架"
2,ides,"ides是一个分布式计算框架,解决了统一大数据+AI开发流程,
简化了数据处理、数据分析、数据挖掘、机器学习等过程"

总共2行数据,第二行存在换行

问题是:

  1. 如何正确读取字段存在换行的csv数据?
  2. 如何将csv数据保存到hive表中,并能正确解析读写?

Activity

  1. bebee4java commented on Dec 1, 2020

    @bebee4java
    OwnerAuthor

    第一个问题比较好解决:
    方法1: 使用spark

    ides> spark.read.option("multiline",true).option("header", true).csv("file:///Users/sgr/test").show

    image
    方法2: 使用ides

    ides> load csv.`file:///Users/sgr/test` where multiline='true' and header='true' as tb;
        | tb.show

    image

    两种方式都能解决读取存在换行的问题,关键是通过指定参数multiline='true'
    ides语法可以将csv数据as tb保存成表,进行后续使用。

    第二个问题可能有些麻烦:
    主要原因是:如果你希望在hive表中数据还是存储成csv格式的文件,就会有问题,因为hive中textfile格式lineDelim只能是换行,所以存在跨行解析异常。类似:

    save tb overwrite into hive.`test.sgrtb` where fileFormat='csv';

    在hive中的结构是:

    CREATE TABLE `sgrtb`(
      `id` string,
      `name` string,
      `desc` string)
    ROW FORMAT SERDE
      'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
    STORED AS INPUTFORMAT
      'org.apache.hadoop.mapred.TextInputFormat'
    OUTPUTFORMAT
      'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    LOCATION
      'hdfs://hadoop:9000/usr/hive/warehouse/test.db/sgrtb'

    查询数据存在跨行问题:
    image

    不过可以通过将fileFormat指定成别的格式解决,比如parquet:

    save tb overwrite into hive.`test.sgrtb` where fileFormat='parquet';

    fileFormat默认就是parquet

    hive表结构为:

    CREATE TABLE `sgrtb`(
      `id` string,
      `name` string,
      `desc` string)
    ROW FORMAT SERDE
      'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
    STORED AS INPUTFORMAT
      'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
    OUTPUTFORMAT
      'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
    LOCATION
      'hdfs://hadoop:9000/usr/hive/warehouse/test.db/sgrtb'

    这时候查询就是正常的:
    image

    不过,如果我在保存hive表的时候,一定要将数据保存成csv格式的文件该怎么办呢??

  2. bebee4java commented on Dec 13, 2020

    @bebee4java
    OwnerAuthor

    💥 对于这个问题,在ides得到了很好得解决:

    我们先模拟一张字段带有换行符的表 multiline_csv_data

    select "1" as id, "文本存在一个换行符'\n'" as text
    union all
    select "2" as id, "文本存在多个换行符'\n\n'" as text
    as multiline_csv_data;

    image

    保存到hive中的表test.multiline_csv_data

    save multiline_csv_data overwrite into hive.`test.multiline_csv_data` where 
    fileFormat='csv' and multiline='true' and fileNum=1;

    这里只需要指定两个关键参数:
    1.fileFormat: 文件格式为csv
    2.multiline: 字段存在跨多行,设置为true
    fileNum=1 以1个文件存储在hdfs

    在hive表中的结构为:

    CREATE TABLE `multiline_csv_data`(
      `id` string COMMENT 'from deserializer',
      `text` string COMMENT 'from deserializer')
    ROW FORMAT SERDE
      'org.apache.hadoop.hive.custom.serde.OpenCSVSerde'
    WITH SERDEPROPERTIES (
      'filenum'='1',
      'multiline'='true')
    STORED AS INPUTFORMAT
      'org.apache.hadoop.hive.custom.inputformat.MultiLineCSVInputFormat'
    OUTPUTFORMAT
      'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
    LOCATION
      'hdfs://hadoop:9000/usr/hive/warehouse/test.db/multiline_csv_data'

    这里我们使用了自定义的serde和inputFormat

    在hdfs上的文件内容为:
    image

    默认以','作为字段分割符, '"'作为字段引号符
    可以通过 separatorChar指定字段分割符,quoteChar指定字段引号符

    读取跨行的csv数据

    • 在ides读取:
    load hive.`test.multiline_csv_data` as multiline_csv_data;

    image
    看见可以正常解析数据,验证行数也是正确!
    image

    • 在hive中读取:

    image
    也可以正常读取。
    注意:hive要想正确读取数据,必须整合我们实现的自定义serde/inputFormat类。
    我这边是把jar包直接放在了$Hive_Home/auxlib目录下:
    image

  3. pinned this issue on Feb 9, 2022
  4. sailhf commented on Sep 6, 2023

    @sailhf

    csv数据中有\r,怎么处理呢?multiLine=true,escape和quote进行转义,都不行

  5. bebee4java commented on Sep 8, 2023

    @bebee4java
    OwnerAuthor

    你用的啥在处理,有示例文件吗

  6. 2108038773 commented on Oct 30, 2025

    @2108038773

    pyspark怎么处理呢,创建表的时候STORED AS PARQUET可以吗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions