2017-08-15 180 views
2

我遇到了從Spark寫入Hive表格的問題。下面的代碼工作得很好;我可以寫表(默認爲實木複合地板格式),並在蜂巢讀回:從Spark指定CSV格式的Hive表格作爲格式

df.write.mode('overwrite').saveAsTable("db.table") 

hive> describe table; 
OK 
val   string 
Time taken: 0.021 seconds, Fetched: 1 row(s) 

但是,如果我指定的格式應該是CSV:

df.write.mode('overwrite').format('csv').saveAsTable("db.table") 

然後我可以保存表,但蜂房無法識別的模式:

hive> describe table; 
OK 
col      array<string>   from deserializer 
Time taken: 0.02 seconds, Fetched: 1 row(s) 

這也是值得注意的是,我可以手動創建一個配置單元表,然後insertInto它:

spark.sql("create table db.table(val string)") 
df.select('val').write.mode("overwrite").insertInto("db.table") 

這樣做,Hive似乎認識到架構。但是這太笨重了,我無法想出一個方法來自動化模式字符串。

+0

Dataframe的模式是什麼?數據中是否有逗號? –

+0

** df.printSchema **的輸出是什麼? –

+0

爲什麼_「笨重」_?您希望創建一個Hive兼容的數據集,因此使用符合Hive的方法創建該數據集似乎是合理的。並且對於記錄來說,使用Parquet更糟糕,因爲默認情況下,Spark不使用與Hive相同的二進制編碼...並且重寫該默認值的方式未記錄在案。 [SPARK-20937] –

回答

1

這是因爲默認情況下Hive SerDe不支持csv

如果你堅持要用csv格式,如下創建表:

CREATE TABLE my_table(a string, b string, ...) 
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' 
WITH SERDEPROPERTIES (
    "separatorChar" = "\t", 
    "quoteChar"  = "'", 
    "escapeChar" = "\\" 
) 
STORED AS TEXTFILE; 

並通過df.write.insertInto

插入數據的詳細信息:

https://cwiki.apache.org/confluence/display/Hive/CSV+Serde

+0

感謝您的信息。我提到這個策略是有效的,但是它很笨重,因爲你必須生成模式字符串('string,b string,...')。這是Spark編寫Spark和Hive都可以​​讀取的表的唯一解決方案嗎? – santon

0

喲你正在創建一個帶有文本格式的表格,並試圖將CSV數據插入到表格中,這可能會遇到問題。正如張彤在答覆中所建議的那樣,使用Hive OpenCSVSerde創建配置單元表。

之後,如果您對Hive查詢語言比數據框更舒適,那麼可以試試這個。

df.registerTempTable("temp") 
spark.sql("insert overwrite db.table select * from temp") 
+0

我不確定我完全按照。 'saveAsTable'的默認值是Parquet,工作正常。當然,Hive SerDe也不支持Parquet。對? – santon

+0

對不起,我感到困惑。我的意思是,用任何需要的格式創建配置單元表。然後只需將數據框中的數據寫入配置單元表。這樣,寫作時就不必擔心格式了。我提供了基本的替代代碼片段,用於從數據框寫入配置表格,而不用擔心格式。 Hive本地支持Parquet SerDe。請參閱https://cwiki.apache.org/confluence/display/Hive/Parquet – Satya

+0

所以說Hive支持Parquet本身但不支持CSV? – santon