Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
bebee4java opened this issue Dec 1, 2020 · 4 comments · Fixed by #7
Open

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

bebee4java opened this issue Dec 1, 2020 · 4 comments · Fixed by #7
Labels
question Further information is requested

Comments

@bebee4java
Copy link
Owner

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

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

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

问题是:

  1. 如何正确读取字段存在换行的csv数据?
  2. 如何将csv数据保存到hive表中,并能正确解析读写?
@bebee4java bebee4java added the question Further information is requested label Dec 1, 2020
@bebee4java
Copy link
Owner Author

bebee4java commented Dec 1, 2020

第一个问题比较好解决:
方法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格式的文件该怎么办呢??

@bebee4java
Copy link
Owner Author

bebee4java commented Dec 13, 2020

💥 对于这个问题,在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

@bebee4java bebee4java pinned this issue Feb 9, 2022
@sailhf
Copy link

sailhf commented Sep 6, 2023

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

@bebee4java
Copy link
Owner Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
2 participants