使用OpenCsv SerDe创建Hive表

时间:2015-02-19 09:51:10

标签: hive opencsv

我使用以下命令创建了表 -

 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; 

但是,创建的表将所有coloumns都作为String!

    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搞乱数据结构吗?

1 个答案:

答案 0 :(得分:3)

通过仔细阅读源代码,看起来OpenCSVSerde将始终输出字符串列,而不考虑HiveQL查询中实际指定的类型。

一个潜在的(不是非常漂亮的)解决方法可能是使用OpenCSVSerde格式化临时表(该定义可以与您当前对cust的定义相同,也许称之为cust_staging如果您的用例是您尝试以该格式加载数据并尝试使用“正确”数据类型在Hive中使用它,则可以填充cust_staging,就像通常加载表格一样然后使用CTAS语句填充目标表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的优秀输入,如果您没有使用“正确”类型实现数据,cust实际上可以是一个视图:

CREATE VIEW `cust` -- All the other stuff is the same

要进一步钻取这一推理线,如果您的用例完全是只读的(您永远不必实际修改此数据),您可以将cust_staging定义为外部表(仍然使用OpenCSVSerde)指向管道分隔的数据文件,然后将cust定义为此外部表的视图。

但是,如果您的用例是您需要以OpenCSVSerde格式存储具有非字符串列的表,那么您仍然可以创建cust_staging表(再次,使用您最初的相同定义)和以相反的方向填充数据:

INSERT INTO TABLE cust_staging SELECT * FROM cust;

如果所有这些仍然感觉不够优雅(可理解) - 解决方案可能是将OpenCSVSerde扩展为自定义SerDe,无需中间登台表即可执行您想要的操作。