首页 文章

将Spark数据框保存到Hive:table不可读,因为“镶木地板不是SequenceFile”

提问于
浏览
9

我想使用PySpark将Spark(v 1.3.0)数据框中的数据保存到Hive表中 .

documentation州:

“spark.sql.hive.convertMetastoreParquet:当设置为false时,Spark SQL将使用Hive SerDe作为镶木桌而不是内置支持 . ”

看看Spark tutorial,似乎可以设置此属性:

from pyspark.sql import HiveContext

sqlContext = HiveContext(sc)
sqlContext.sql("SET spark.sql.hive.convertMetastoreParquet=false")

# code to create dataframe

my_dataframe.saveAsTable("my_dataframe")

但是,当我尝试查询Hive中保存的表时,它返回:

hive> select * from my_dataframe;
OK
Failed with exception java.io.IOException:java.io.IOException: 
hdfs://hadoop01.woolford.io:8020/user/hive/warehouse/my_dataframe/part-r-00001.parquet
not a SequenceFile

如何保存表格,使其在Hive中立即可读?

3 回答

  • 3

    我去过那儿...
    API在这一点上有点误导 .
    DataFrame.saveAsTable 确实 not 创建一个Hive表,但是内部Spark表源 .
    它还将一些东西存储到Hive Metastore中,但不是你想要的东西 .
    这个remark是由关于Spark 1.3的spark-user邮件列表制作的 .

    如果您希望从Spark创建Hive表,可以使用以下方法:
    1.通过SparkSQL使用 Create Table ... 进行Hive Metastore .
    2.使用 DataFrame.insertInto(tableName, overwriteMode) 作为实际数据(Spark 1.3)

  • 16

    我上周遇到了这个问题,并找到了解决方法

    这是故事:如果我创建没有partitionBy的表,我可以在Hive中看到表:

    spark-shell>someDF.write.mode(SaveMode.Overwrite)
                      .format("parquet")
                      .saveAsTable("TBL_HIVE_IS_HAPPY")
    
    hive> desc TBL_HIVE_IS_HAPPY;
          OK
          user_id                   string                                      
          email                     string                                      
          ts                        string
    

    但是如果我这样做,Hive无法理解表模式(模式是空的......):

    spark-shell>someDF.write.mode(SaveMode.Overwrite)
                      .format("parquet")
                      .saveAsTable("TBL_HIVE_IS_NOT_HAPPY")
    
    hive> desc TBL_HIVE_IS_NOT_HAPPY;
          # col_name                data_type               from_deserializer
    

    [Solution]:

    spark-shell>sqlContext.sql("SET spark.sql.hive.convertMetastoreParquet=false")
    spark-shell>df.write
                  .partitionBy("ts")
                  .mode(SaveMode.Overwrite)
                  .saveAsTable("Happy_HIVE")//Suppose this table is saved at /apps/hive/warehouse/Happy_HIVE
    
    
    hive> DROP TABLE IF EXISTS Happy_HIVE;
    hive> CREATE EXTERNAL TABLE Happy_HIVE (user_id string,email string,ts string)
                                           PARTITIONED BY(day STRING)
                                           STORED AS PARQUET
                                           LOCATION '/apps/hive/warehouse/Happy_HIVE';
    hive> MSCK REPAIR TABLE Happy_HIVE;
    

    问题是通过Dataframe API(partitionBy saveAsTable)创建的数据源表与Hive不兼容 . (请参阅link) . 通过doc中的建议将 spark.sql.hive.convertMetastoreParquet 设置为false,Spark只将数据放到HDFS上,但是在Spark 1.6.1中测试了这个并且它对我有用 . 我希望这有帮助!

  • 0

    我在pyspark,spark版本2.3.0中完成了:

    创建我们需要保存/覆盖数据的空表,如:

    create table databaseName.NewTableName like databaseName.OldTableName;
    

    然后在命令下运行:

    df1.write.mode("overwrite").partitionBy("year","month","day").format("parquet").saveAsTable("databaseName.NewTableName");
    

    问题是你不能用hive阅读这个表,但你可以用spark阅读 .

相关问题