我遇到了从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)
值得注意的是,我可以手动创建Hive表,然后insertInto
:
spark.sql("create table db.table(val string)")
df.select('val').write.mode("overwrite").insertInto("db.table")
这样做,Hive似乎认识到架构。但这很笨重,我无法想办法自动化架构字符串。
答案 0 :(得分: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
欲了解更多信息:
答案 1 :(得分:0)
您正在创建一个包含文本格式的表,并尝试将CSV数据插入其中,这可能会导致问题。因此,如张彤的回答所示,使用配置单元OpenCSVSerde创建配置表。
之后,如果您对Hive查询语言比对数据帧更熟悉,可以试试这个。
df.registerTempTable("temp")
spark.sql("insert overwrite db.table select * from temp")
答案 2 :(得分:0)
之所以发生这种情况,是因为HiveSerde在csv上与Spark所使用的不同。默认情况下,配置单元使用TEXTFORMAT,并且在创建表时必须指定分隔符。
一种选择是从Spark写入时使用insertInto API代替 saveAsTable 。使用 insertInto 时,Spark将数据框的内容写入指定的表。但它要求数据框的架构与表的架构相同。列的位置在这里很重要,因为它会忽略列名。
Seq((5, 6)).toDF("a", "b").write.insertInto("t1")