Ошибка при сохранении значения карты в Spark dataframe (scala) — ожидаемый столбец, фактическая карта [int, string]

#scala #apache-spark #apache-spark-sql #key-value

#scala #apache-spark #apache-spark-sql #ключ-значение

Вопрос:

У меня есть пара значений ключа в Map [int, string]. Мне нужно сохранить это значение в таблице Hive, используя spark dataframe. Но я получаю ошибку — Expected column, actual Map[int,string]

Код:

 val dbValuePairs = Array(2019,10)
val dbkey = dbValuePairs.map(x => x).zipWithIndex.map(t => (t._2, t._1)).toMap

val dqMetrics = spark.sql("select * from dqMetricsStagingTbl")
  .withColumn("Dataset_Name", lit(Dataset_Name))
  .withColumn("Key", dbkey)
dqMetrics.createOrReplaceTempView("tempTable")

spark.sql("create table if not exists hivetable AS select * from tempTable")

dqMetrics.write.mode("append").insertInto(hivetable)
  

Пожалуйста, помогите! Ошибка в withColumn("Key", dbkey) строке

Ответ №1:

Посмотрите на withColumn сигнатуру функции Spark:

 def withColumn(colName: String, col: Column): DataFrame 
  

он принимает два аргумента: colName as String и col as Column .

ваш dbkey тип — Map[Int, Int] это не Column :

 val dbkey: Map[Int, Int] = dbValuePairs.map(x => x).zipWithIndex.map(t => (t._2, t._1)).toMap
  

если вы хотите сохранить Map в столбце таблицы, вы можете использовать map функцию, которая принимает последовательность Column :

 // from object org.apache.spark.sql.functions
def map(cols: Column*): Column
  

таким образом, вы можете преобразовать свой dbkey в Seq[Column] и передать его в withColumn функцию:

 val dbValuePairs = Array(2019,10)
val dbkey: Map[Int, Int] = dbValuePairs.map(x => x).zipWithIndex.map(t => (t._2, t._1)).toMap
val dbkeyColumnSeq: Seq[Column] = dbkey.flatMap(t => Seq(lit(t._2), lit(t._1))).toSeq

val dqMetrics = spark.sql("select * from dqMetricsStagingTbl")
  .withColumn("Dataset_Name", lit(""))
  .withColumn("Key", map(dbkeyColumnSeq:_*))