Spark DataFrame 写入HIve 出现HiveFileFormat`. It doesn't match the specified format `ParquetFileFormat`

场景

现在有一个需求,解析一个csv文件,然后写入hive已经存在的表中,就出现了这个错

org.apache.spark.sql.AnalysisException: The format of the existing table arcsoft_analysis.zz_table is `HiveFileFormat`. It doesn't match the specified format `ParquetFileFormat`.;

解析:

       如果用命令行创建的hive表,会根据hive的hive.default.fileformat,这个配置来规定hive文件的格式,其中fileformat一般有4中,分别是TextFile、SequenceFile、RCFile、ORC。默认情况下,不指定的话,是TextFile。那么如何在hive建表的时候指定呢? 就在建表语句最后加上stored as TextFile 或者stored as RCFile等等就可以了。

       但是df.write默认的format是parquet + snappy。如果表是用hive命令行创建的,就不符合格式,所以就会报错。如果表是提前不存在的,那么就不会有什么问题。

解决:

第一种:

个人会用这一种

df.write.format("Hive").mode(SaveMode.Append).saveAsTable("zz_table")

将format设置为Hive以后,无论hive建表的时候,使用的fileformat使用的是哪一种,都是没有关系的

直接上测试代码:

  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().
      appName("aa")
      .enableHiveSupport()
      .getOrCreate()
    //切换namespace
    spark.sql("use arcsoft_analysis")
    //获取原表的schema
    val mychema = spark.table("closeli_user_info").schema
    //生产dataframe
    val df = spark.read.option("header",true)
      .option("inferSchema",false)
      .option("delimiter",",")
      .schema(mychema)
      .csv("/user/root/closeli_user_info.csv")
    //使用saveAsTable的方式写入hive
    df.write.format("Hive").mode(SaveMode.Append).saveAsTable("zz_table")
    spark.close()
  }

第二种:   

其实,还可以一种方式,就是使用insertInto,但是不太建议。因为在insertInto源码中,这样写道:

insertInto插入的时候,是根据列的位置插入,而不是根据列的名字。表的format和设置的options也会被忽略。所以不是很推荐,但是也能达到目标。

df.write.insertInto("zz_table")
/**
   * Inserts the content of the `DataFrame` to the specified table. It requires that
   * the schema of the `DataFrame` is the same as the schema of the table.
   *
   * @note Unlike `saveAsTable`, `insertInto` ignores the column names and just uses position-based
   * resolution. For example:
   *
   * {{{
   *    scala> Seq((1, 2)).toDF("i", "j").write.mode("overwrite").saveAsTable("t1")
   *    scala> Seq((3, 4)).toDF("j", "i").write.insertInto("t1")
   *    scala> Seq((5, 6)).toDF("a", "b").write.insertInto("t1")
   *    scala> sql("select * from t1").show
   *    +---+---+
   *    |  i|  j|
   *    +---+---+
   *    |  5|  6|
   *    |  3|  4|
   *    |  1|  2|
   *    +---+---+
   * }}}
   *
   * Because it inserts data to an existing table, format or options will be ignored.
   *
   * @since 1.4.0
   */

第三种:

还有一种方式,就是先将dataframe注册成临时表,然后通过sql的方式,插入

df.createOrReplaceTempView("temp_tab")
spark.sql("insert into zz_table select * from temp_tab")

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值