将 CSV 数据加载到 Hive ORC 表中
Loading CSV data into Hive ORC tables
我有如下数据:
id,name,description,category
1,sid,I am don,right?,production
我遵循了 this link 中提供的步骤。主要问题是当我将数据插入临时 table 时,3rd column
中的数据被分离并推入第 4 列,即当它在 right
字之前看到 ","
时它划分数据并将其推入下一列。这是因为我正在获取 CSV 格式的数据,因此在创建临时 table 时将分隔符应用为 ","
。所以,有一个混乱。我该如何解决??
按照 xenodevil
建议的步骤后,我 运行 下面的查询出现错误:
insert into perTable select * from sampleTable;
其中 sampleTable 是温度 table,perTable 是 ORC table,sampleTable 数据如下所示:
+-----------------+-------------------+--------------------------+-----------------------+--+
| sampletable.id | sampletable.name | sampletable.description | sampletable.category |
+-----------------+-------------------+--------------------------+-----------------------+--+
| 1 | sid | I am don,right? | production |
+-----------------+-------------------+--------------------------+-----------------------+--+
但出现以下错误:
ERROR : Status: Failed
ERROR : Vertex failed, vertexName=Map 1, vertexId=vertex_1560140822404_0022_1_00, diagnostics=[Task failed, taskId=task_1560140822404_0022_1_00_000000, diagnostics=[TaskAttempt 0 failed, info=[Error: Failure while running task:java.lang.RuntimeException: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row {"id":"1","name":"sid","description":"I am don,right?","category":"production"}
at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.initializeAndRunProcessor(TezProcessor.java:173)
at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.run(TezProcessor.java:139)
那么这里的问题是什么??
您将如何确定第 3 列中有多少个逗号?如果它可以包含任何文本,那么它可以包含任意数量的逗号。这必须在文件生成级别进行控制,即在写入数据时而不是在稍后尝试以 CSV 格式读取数据时。在生成 CVS 文件时,您可以
- 在作为数据一部分的每个逗号前放置一个转义字符,而不是逗号分隔符
- 用双引号将每列的文本括起来
- 仅用双引号将存在定界字符(逗号)的列括起来
这些是可以可靠地解决此类问题的一些常见做法。
一种不可靠的方法,非常针对您提供的数据,并且只会解决您第 3 列中的冗余逗号,即使用以下 RegexSerDe 作为您的 ROW FORMAT
([0-9]*),([a-zA-Z ]*),([A-Za-z ,?]*),([A-Za-z ,]*)
要设置它,您需要将 table 的 DDL 修改为如下内容:
CREATE TABLE `your_database_name.your_table_name`(
`id` string,
`name` string,
`description` string,
`category` string
)
COMMENT 'Your Comment'
ROW FORMAT SERDE
'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'input.regex'='([0-9]*),([a-zA-Z ]*),([A-Za-z ,?]*),([A-Za-z ,]*)'
)
STORED AS TEXT
;
我在这里检查了正则表达式,但您需要调整 DDL 语法以满足您的需要。
您可以使用此示例流在 Hive 中加载数据 table。
1) 由于 ,
分隔符存在歧义,请更新文件以使用 |
分隔符来标识实际字段。所以,文件看起来像这样。我们称之为 data.csv
.
1|sid|I am don,right?|production
2) 在 Hive
中创建一个 table,指定正确的列分隔符。
hive> CREATE TABLE t1_tmp
(
id string,
name string,
description string,
category string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n';
3) 从本地文件加载数据
hive> LOAD DATA LOCAL INPATH '/path/to/data.csv' INTO TABLE t1_tmp;
4) 查看数据
hive> select * from t1_tmp;
OK
t1_tmp.id t1_tmp.name t1_tmp.description t1_tmp.category
1 sid I am don,right? production
我有如下数据:
id,name,description,category
1,sid,I am don,right?,production
我遵循了 this link 中提供的步骤。主要问题是当我将数据插入临时 table 时,3rd column
中的数据被分离并推入第 4 列,即当它在 right
字之前看到 ","
时它划分数据并将其推入下一列。这是因为我正在获取 CSV 格式的数据,因此在创建临时 table 时将分隔符应用为 ","
。所以,有一个混乱。我该如何解决??
按照 xenodevil
建议的步骤后,我 运行 下面的查询出现错误:
insert into perTable select * from sampleTable;
其中 sampleTable 是温度 table,perTable 是 ORC table,sampleTable 数据如下所示:
+-----------------+-------------------+--------------------------+-----------------------+--+
| sampletable.id | sampletable.name | sampletable.description | sampletable.category |
+-----------------+-------------------+--------------------------+-----------------------+--+
| 1 | sid | I am don,right? | production |
+-----------------+-------------------+--------------------------+-----------------------+--+
但出现以下错误:
ERROR : Status: Failed
ERROR : Vertex failed, vertexName=Map 1, vertexId=vertex_1560140822404_0022_1_00, diagnostics=[Task failed, taskId=task_1560140822404_0022_1_00_000000, diagnostics=[TaskAttempt 0 failed, info=[Error: Failure while running task:java.lang.RuntimeException: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row {"id":"1","name":"sid","description":"I am don,right?","category":"production"}
at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.initializeAndRunProcessor(TezProcessor.java:173)
at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.run(TezProcessor.java:139)
那么这里的问题是什么??
您将如何确定第 3 列中有多少个逗号?如果它可以包含任何文本,那么它可以包含任意数量的逗号。这必须在文件生成级别进行控制,即在写入数据时而不是在稍后尝试以 CSV 格式读取数据时。在生成 CVS 文件时,您可以
- 在作为数据一部分的每个逗号前放置一个转义字符,而不是逗号分隔符
- 用双引号将每列的文本括起来
- 仅用双引号将存在定界字符(逗号)的列括起来
这些是可以可靠地解决此类问题的一些常见做法。
一种不可靠的方法,非常针对您提供的数据,并且只会解决您第 3 列中的冗余逗号,即使用以下 RegexSerDe 作为您的 ROW FORMAT
([0-9]*),([a-zA-Z ]*),([A-Za-z ,?]*),([A-Za-z ,]*)
要设置它,您需要将 table 的 DDL 修改为如下内容:
CREATE TABLE `your_database_name.your_table_name`(
`id` string,
`name` string,
`description` string,
`category` string
)
COMMENT 'Your Comment'
ROW FORMAT SERDE
'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'input.regex'='([0-9]*),([a-zA-Z ]*),([A-Za-z ,?]*),([A-Za-z ,]*)'
)
STORED AS TEXT
;
我在这里检查了正则表达式,但您需要调整 DDL 语法以满足您的需要。
您可以使用此示例流在 Hive 中加载数据 table。
1) 由于 ,
分隔符存在歧义,请更新文件以使用 |
分隔符来标识实际字段。所以,文件看起来像这样。我们称之为 data.csv
.
1|sid|I am don,right?|production
2) 在 Hive
中创建一个 table,指定正确的列分隔符。
hive> CREATE TABLE t1_tmp
(
id string,
name string,
description string,
category string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n';
3) 从本地文件加载数据
hive> LOAD DATA LOCAL INPATH '/path/to/data.csv' INTO TABLE t1_tmp;
4) 查看数据
hive> select * from t1_tmp;
OK
t1_tmp.id t1_tmp.name t1_tmp.description t1_tmp.category
1 sid I am don,right? production