我在写spark的Hive表时遇到了问题。下面的代码工作得很好;我可以写入表(默认为Parquet格式)并在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无法识别架构:
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似乎认识到模式。但这很笨拙,而且我也找不出一种方法来自动生成模式字符串。
3条答案
按热度按时间klh5stk11#
那是因为
Hive SerDe
不支持csv
默认情况下。如果你坚持使用
csv
格式,创建如下表:并通过
df.write.insertInto
更多信息:https://cwiki.apache.org/confluence/display/hive/csv+serde
cig3rfwq2#
这是因为hiveserde与spark使用的不同。配置单元默认使用textformat,并且在创建表时必须指定分隔符。
一种选择是在从spark写入时使用insertintoapi而不是saveastable。使用insertinto时,spark将Dataframe的内容写入指定的表。但它要求Dataframe的模式与表的模式相同。列的位置在这里很重要,因为它忽略了列名。
Seq((5, 6)).toDF("a", "b").write.insertInto("t1")
3xiyfsfu3#
您正在创建一个文本格式的表,并试图将csv数据插入其中,这可能会导致问题。因此,正如张彤在回答中建议的那样,使用hiveopencsvserde创建hive表。
在那之后,如果您对配置单元查询语言比Dataframe更熟悉,您可以试试这个。