使用 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.