2017-08-15 69 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