从Spark编写Hive表,指定CSV作为格式

时间:2017-08-15 00:00:31

标签: apache-spark hive pyspark apache-spark-sql

我遇到了从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似乎认识到架构。但这很笨重,我无法想办法自动化架构字符串。

3 个答案:

答案 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

插入数据

欲了解更多信息:

  

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

答案 1 :(得分:0)

您正在创建一个包含文本格式的表,并尝试将CS​​V数据插入其中,这可能会导致问题。因此,如张彤的回答所示,使用配置单元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")