Иерархия типов набора данных Spark Scala

Попытка заставить классы, расширяющие W, иметь метод get, который возвращает набор данных подкласса WR.

abstract class WR

case class TGWR(
          a: String,
          b: String
        ) extends WR

abstract class W {

  def get[T <: WR](): Dataset[T]

}


class TGW(sparkSession: SparkSession) extends W {

  override def get[TGWR](): Dataset[TGWR] = {
    import sparkSession.implicits._

    Seq(TGWR("dd","dd").toDF().as[TGWR]
  }

}

Ошибка компиляции:

Unable to find encoder for type stored in a Dataset.  Primitive types (Int, String, etc) and Product types (case classes) are supported by importing spark.implicits._  Support for serializing other types will be added in future releases.

Если я изменю функцию get на следующую:

  def get(): Dataset[TGWR]

а также

  override def get(): Dataset[TGWR] = {...

он компилируется - поэтому я подозреваю, что проблема связана с иерархией наследования / типов.


person devopslife    schedule 11.02.2019    source источник


Ответы (1)


Забудьте мой комментарий, я перечитал ваш вопрос и заметил простую проблему.

Здесь override def get[TGWR] вы не говорите, что этот класс создает экземпляры TGWR, но вы создаете новый параметр типа с именем TGWR, который затеняет ваш настоящий тип.
Я исправил это с помощью следующего кода :

import org.apache.spark.sql.{SparkSession, Dataset}

abstract class WR extends Product with Serializable

final case class TGWR(a: String, b: String) extends WR

abstract class W[T <: WR] {
  def get(): Dataset[T]
}

final class TGW(spark: SparkSession) extends W[TGWR] {
  override def get(): Dataset[TGWR] = {
    import spark.implicits._
    Seq(TGWR("dd","dd")).toDF().as[TGWR]
  }
}

Что вы можете использовать правильно:

val spark = SparkSession.builder.master("local[*]").getOrCreate()
(new TGW(spark)).get()
// res1: org.apache.spark.sql.Dataset[TGWR] = [a: string, b: string]
res1.show()
// +---+---+
// |  a|  b|
// +---+---+
// | dd| dd|
// +---+---+

Надеюсь, это именно то, что вы ищете.
Не сомневайтесь, попросите разъяснений.

person Luis Miguel Mejía Suárez    schedule 11.02.2019