【问题标题】:how to insert dataframe having map column in hive table如何在配置单元表中插入具有地图列的数据框
【发布时间】:2020-02-27 17:44:07
【问题描述】:

我有一个包含多列的数据框,其中一列是 map(string,string) 类型。我可以打印这个数据框,其列作为地图,将数据作为地图(“PUN”->“Pune”)。我想将此数据帧写入 hive 表(存储为 avro),该表具有与 map 类型相同的列。

Df.withcolumn("cname", lit("Pune"))
withcolumn("city_code_name", map(lit("PUN"), col("cname"))
Df.show(false)

//table - created external hive table..stored as avro..with avro schema

删除此地图类型列后,我可以将数据框保存到 hive avro 表。

保存到hive表的方式:

  1. spark.save - 保存 avro 文件
  2. spark.sql - 使用 avro 文件位置在 hive 表上创建分区

【问题讨论】:

    标签: apache-spark hadoop hive apache-spark-sql complextype


    【解决方案1】:

    see this test case as an example from spark tests

      test("Insert MapType.valueContainsNull == false") {
        val schema = StructType(Seq(
          StructField("m", MapType(StringType, StringType, valueContainsNull = false))))
        val rowRDD = spark.sparkContext.parallelize(
          (1 to 100).map(i => Row(Map(s"key$i" -> s"value$i"))))
        val df = spark.createDataFrame(rowRDD, schema)
        df.createOrReplaceTempView("tableWithMapValue")
        sql("CREATE TABLE hiveTableWithMapValue(m Map <STRING, STRING>)")
        sql("INSERT OVERWRITE TABLE hiveTableWithMapValue SELECT m FROM tableWithMapValue")
    
        checkAnswer(
          sql("SELECT * FROM hiveTableWithMapValue"),
          rowRDD.collect().toSeq)
    
        sql("DROP TABLE hiveTableWithMapValue")
      }
    

    如果你想要保存选项,那么你可以尝试使用 saveAsTable 显示here

    Seq(9 -> "x").toDF("i", "j")
            .write.format("hive").mode(SaveMode.Overwrite).option("fileFormat", "avro").saveAsTable("t")
    

    yourdataframewithmapcolumn.write.partitionBy 是创建分区的方式。

    【讨论】:

    • 我想避免创建临时表并保持与上述方法相同的保存方式,只想使用新的地图类型列更新数据框并将其直接保存到存储为 avro 的配置单元表中。
    • ` spark.createDataFrame(df.rdd, st) .write.format("com.databricks.spark.avro").mode(SaveMode.Overwrite).save(path)` - 使用这个将 avro 文件保存在给定路径 sparkSession.sql(s"alter table tablename ADD partition(p1='210') location 'path'") - 用于创建分区 注意 - 这在没有映射类型列的情况下工作完美,并且在此代码运行之前单独创建 hive 表
    • ERROR- Caused by: java.lang.NullPointerException: in topLevelRecord in union in map in &lt;fieldname&gt;
    【解决方案2】:

    您可以通过saveAsTable 实现这一目标 示例:

        Df\
            .write\
            .saveAsTable(name='tableName',
                         format='com.databricks.spark.avro',
                         mode='append',
                         path='avroFileLocation')
    

    将模式选项更改为适合您的任何选项

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-04
      • 2022-01-24
      • 2018-05-16
      • 1970-01-01
      • 2021-12-11
      • 2020-07-26
      • 2021-12-20
      • 1970-01-01
      相关资源
      最近更新 更多