从spark写入配置单元表指定csv作为格式

3htmauhk  于 2021-06-26  发布在  Hive
关注(0)|答案(3)|浏览(477)

我在写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似乎认识到模式。但这很笨拙,而且我也找不出一种方法来自动生成模式字符串。

klh5stk1

klh5stk11#

那是因为 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

cig3rfwq

cig3rfwq2#

这是因为hiveserde与spark使用的不同。配置单元默认使用textformat,并且在创建表时必须指定分隔符。
一种选择是在从spark写入时使用insertintoapi而不是saveastable。使用insertinto时,spark将Dataframe的内容写入指定的表。但它要求Dataframe的模式与表的模式相同。列的位置在这里很重要,因为它忽略了列名。 Seq((5, 6)).toDF("a", "b").write.insertInto("t1")

3xiyfsfu

3xiyfsfu3#

您正在创建一个文本格式的表,并试图将csv数据插入其中,这可能会导致问题。因此,正如张彤在回答中建议的那样,使用hiveopencsvserde创建hive表。
在那之后,如果您对配置单元查询语言比Dataframe更熟悉,您可以试试这个。

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

相关问题