Spark SQL HiveContext - saveAsTable 创建错误的架构
Posted
技术标签:
【中文标题】Spark SQL HiveContext - saveAsTable 创建错误的架构【英文标题】:Spark SQL HiveContext - saveAsTable creates wrong schema 【发布时间】:2015-05-14 09:54:01 【问题描述】:我尝试将 Dataframe 存储到 Spark 1.3.0 (PySpark) 中的持久 Hive 表中。这是我的代码:
sc = SparkContext(appName="HiveTest")
hc = HiveContext(sc)
peopleRDD = sc.parallelize(['"name":"Yin","age":30'])
peopleDF = hc.jsonRDD(peopleRDD)
peopleDF.printSchema()
#root
# |-- age: long (nullable = true)
# |-- name: string (nullable = true)
peopleDF.saveAsTable("peopleHive")
我期望的 Hive 输出表是:
Column Data Type Comments
age long from deserializer
name string from deserializer
但上述代码实际输出的Hive表是:
Column Data Type Comments
col array<string> from deserializer
为什么 Hive 表与 DataFrame 的架构不同?如何达到预期的输出?
【问题讨论】:
【参考方案1】:不是架构错了。 Hive 无法正确读取 Spark 创建的表,因为它甚至还没有正确的 parquet serde。
如果您执行sqlCtx.sql('desc peopleHive').show()
,它应该显示正确的架构。
或者您可以使用 spark-sql 客户端而不是 hive。您还可以使用 create table 语法创建外部表,其工作方式与 Hive 类似,但 Spark 对 parquet 的支持要好得多。
【讨论】:
没错,hc.sql('desc peopleHive').show()
显示了正确的架构。我误解了 Spark 文档。我相信 saveAsTable 确实创建了一个可以从 Spark 外部使用的 Hive 表。我现在明白事实并非如此。为此,我需要运行peopleDF.registerTempTable("peopleHive") hc.sql('create table peopleHive as select name, age from peopleHive')
这是向该表添加行的一种方式?或者我必须使用分区?有办法或指定正确的serde
和saveAsTable
以便Imapala
或Hive
可以阅读吗?
@nanounanue, 1) 是的,有一种方法可以将行添加到现有表中,并且您不需要使用分区:hc.sql('insert into table peopleHive select name, age from peopleHive')
。 2) 我还没有找到使用saveAsTable()
以便Hive 可以读取它的方法。如果你这样做,请告诉我。【参考方案2】:
类似覆盖行为的解决方法是
val viewName = "tempView"
df.createTempView(viewName)
df.sparkSession.sql(s"DROP TABLE IF EXISTS $tableName")
df.sparkSession.sql(
s"""CREATE TABLE $tableName AS
| select * from $viewName
""".stripMargin)
df.sparkSession.catalog.dropTempView(viewName)
【讨论】:
以上是关于Spark SQL HiveContext - saveAsTable 创建错误的架构的主要内容,如果未能解决你的问题,请参考以下文章
Spark HiveContext 使用 sql 方法应用 IN 操作
Spark SQL HiveContext - saveAsTable 创建错误的架构
Spark SQL(通过 HiveContext 进行 Hive 查询)总是创建 31 个分区
使用 spark hivecontext 读取外部 hive 分区表的问题