使用 OpenCsv SerDe 创建 Hive table
Hive table creation using OpenCsv SerDe
我使用以下命令创建了 table -
create table cust(event int, pid int, REQ_FROM_IP int, REQ_CITY_ID int, REQ_STATE_ID int, REQ_COUNTRY_ID int, key String)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
"separatorChar" = "|",
"quoteChar" = "'",
"escapeChar" = "\"
)STORED AS TEXTFILE;
但是创建的 table 的所有列都是字符串!
desc cust;
OK
event string from deserializer
pid string from deserializer
req_from_ip string from deserializer
req_city_id string from deserializer
req_state_id string from deserializer
req_country_id string from deserializer
key string from deserializer
是 SerDe 弄乱了数据结构吗?
从仔细阅读源代码来看,OpenCSVSerde 似乎总是输出字符串列,而不考虑 HiveQL 查询中实际指定的类型。
一个潜在的(不是很漂亮)解决方法可能是使用 OpenCSVSerde 格式化暂存 table(定义可以与您当前对 cust
的定义相同,也许调用它 cust_staging
。如果您的用例是您尝试以该格式加载数据并尝试在 Hive 中使用 "correct" 数据类型使用它,您可以将 cust_staging
填充为您通常会加载 table,然后使用如下 CTAS 语句填充目标 table cust
:
CREATE TABLE cust AS SELECT
CAST(event AS INT) AS event,
CAST(pid AS INT) AS pid,
CAST(REQ_FROM_IP AS INT) AS REQ_FROM_IP,
CAST(REQ_CITY_ID AS INT) AS REQ_CITY_ID,
CAST(REQ_STATE_ID AS INT) AS REQ_STATE_ID,
CAST(REQ_COUNTRY_ID AS INT) AS REQ_COUNTRY_ID,
key
FROM cust_staging;
现在 cust
将具有您期望的列类型:
hive> DESCRIBE cust;
OK
event int
pid int
req_from_ip int
req_city_id int
req_state_id int
req_country_id int
key string
Time taken: 0.546 seconds, Fetched: 7 row(s)
根据@JeremyBeard 的出色输入,如果您可以从不使用它的 "correct" 类型具体化数据,那么 cust
实际上可以是一个视图:
CREATE VIEW `cust` -- All the other stuff is the same
为了进一步展开这一推理,如果您的用例完全是只读的(您永远不必实际修改此数据),您可以将 cust_staging
定义为外部 table(仍然使用 OpenCSVSerde)指向管道分隔的数据文件,然后将 cust
定义为此外部 table.
的视图
但是,如果您的用例是您需要以 OpenCSVSerde 格式存储带有非字符串列的 table,那么您仍然可以创建 cust_staging
table(再次,具有与您最初的相同定义)并以相反方向填充数据:
INSERT INTO TABLE cust_staging SELECT * FROM cust;
如果所有这些仍然感觉不够优雅(可以理解)- 解决方案可能是将 OpenCSVSerde 扩展为自定义 SerDe,它将执行您想要的操作而无需中间阶段 tables.
我使用以下命令创建了 table -
create table cust(event int, pid int, REQ_FROM_IP int, REQ_CITY_ID int, REQ_STATE_ID int, REQ_COUNTRY_ID int, key String)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
"separatorChar" = "|",
"quoteChar" = "'",
"escapeChar" = "\"
)STORED AS TEXTFILE;
但是创建的 table 的所有列都是字符串!
desc cust;
OK
event string from deserializer
pid string from deserializer
req_from_ip string from deserializer
req_city_id string from deserializer
req_state_id string from deserializer
req_country_id string from deserializer
key string from deserializer
是 SerDe 弄乱了数据结构吗?
从仔细阅读源代码来看,OpenCSVSerde 似乎总是输出字符串列,而不考虑 HiveQL 查询中实际指定的类型。
一个潜在的(不是很漂亮)解决方法可能是使用 OpenCSVSerde 格式化暂存 table(定义可以与您当前对 cust
的定义相同,也许调用它 cust_staging
。如果您的用例是您尝试以该格式加载数据并尝试在 Hive 中使用 "correct" 数据类型使用它,您可以将 cust_staging
填充为您通常会加载 table,然后使用如下 CTAS 语句填充目标 table cust
:
CREATE TABLE cust AS SELECT
CAST(event AS INT) AS event,
CAST(pid AS INT) AS pid,
CAST(REQ_FROM_IP AS INT) AS REQ_FROM_IP,
CAST(REQ_CITY_ID AS INT) AS REQ_CITY_ID,
CAST(REQ_STATE_ID AS INT) AS REQ_STATE_ID,
CAST(REQ_COUNTRY_ID AS INT) AS REQ_COUNTRY_ID,
key
FROM cust_staging;
现在 cust
将具有您期望的列类型:
hive> DESCRIBE cust;
OK
event int
pid int
req_from_ip int
req_city_id int
req_state_id int
req_country_id int
key string
Time taken: 0.546 seconds, Fetched: 7 row(s)
根据@JeremyBeard 的出色输入,如果您可以从不使用它的 "correct" 类型具体化数据,那么 cust
实际上可以是一个视图:
CREATE VIEW `cust` -- All the other stuff is the same
为了进一步展开这一推理,如果您的用例完全是只读的(您永远不必实际修改此数据),您可以将 cust_staging
定义为外部 table(仍然使用 OpenCSVSerde)指向管道分隔的数据文件,然后将 cust
定义为此外部 table.
但是,如果您的用例是您需要以 OpenCSVSerde 格式存储带有非字符串列的 table,那么您仍然可以创建 cust_staging
table(再次,具有与您最初的相同定义)并以相反方向填充数据:
INSERT INTO TABLE cust_staging SELECT * FROM cust;
如果所有这些仍然感觉不够优雅(可以理解)- 解决方案可能是将 OpenCSVSerde 扩展为自定义 SerDe,它将执行您想要的操作而无需中间阶段 tables.