ides
ides copied to clipboard
CSV文件字段存在换行符,如何正常读写存储到hive表?
csv文件某些文本字段里存在换行符,如:
id,name,desc
1,spark,"spark是一个分布式计算框架"
2,ides,"ides是一个分布式计算框架,解决了统一大数据+AI开发流程,
简化了数据处理、数据分析、数据挖掘、机器学习等过程"
总共2行数据,第二行存在换行
问题是:
- 如何正确读取字段存在换行的csv数据?
- 如何将csv数据保存到hive表中,并能正确解析读写?
第一个问题比较好解决: 方法1: 使用spark
ides> spark.read.option("multiline",true).option("header", true).csv("file:///Users/sgr/test").show
方法2: 使用ides
ides> load csv.`file:///Users/sgr/test` where multiline='true' and header='true' as tb;
| tb.show

两种方式都能解决读取存在换行的问题,关键是通过指定参数
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'
查询数据存在跨行问题:

不过可以通过将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'
这时候查询就是正常的:

不过,如果我在保存hive表的时候,一定要将数据保存成csv格式的文件该怎么办呢??
💥 对于这个问题,在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;

保存到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: 文件格式为
csv2.multiline: 字段存在跨多行,设置为truefileNum=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上的文件内容为:

默认以','作为字段分割符, '"'作为字段引号符 可以通过
separatorChar指定字段分割符,quoteChar指定字段引号符
读取跨行的csv数据
- 在ides读取:
load hive.`test.multiline_csv_data` as multiline_csv_data;
看见可以正常解析数据,验证行数也是正确!

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

csv数据中有\r,怎么处理呢?multiLine=true,escape和quote进行转义,都不行
你用的啥在处理,有示例文件吗