【问题标题】:scala generic encoder for spark case class用于火花案例类的 scala 通用编码器
【发布时间】:2017-10-30 01:56:05
【问题描述】:

我怎样才能让这个方法编译。奇怪的是,sparksimplicit 已经被导入了。

def loadDsFromHive[T <: Product](tableName: String, spark: SparkSession): Dataset[T] = {
    import spark.implicits._
    spark.sql(s"SELECT * FROM $tableName").as[T]
  }

这是错误:

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.
[error]     spark.sql(s"SELECT * FROM $tableName").as[T]

【问题讨论】:

  • Product中除了原语还有哪些其他类型?
  • 我想使用一个案例类并且只使用原语。但是上面的这个 sn-p 字面上不会编译。

标签: scala apache-spark generics apache-spark-dataset apache-spark-encoders


【解决方案1】:

根据org.apache.spark.sql.SQLImplicits的源代码,您需要为您的类型提供类型类TypeTag,以便隐式Encoder存在:

import scala.reflect.runtime.universe.TypeTag
def loadDsFromHive[T <: Product: TypeTag](tableName: String, spark: SparkSession): Dataset[T] = ...

【讨论】:

  • 在我的例子中,T 是一个类级别的类型参数。我添加了: TypeTag,但我仍然收到该消息(我也在导入implicits)
  • 还需要添加Encoder,即[T: Encoder : TypeTag]
  • 按照@lfk 的建议添加Encoder 会有所帮助,但仍会产生Unable to find encoder for type ExtendedProduct 之类的错误。一种解决方法是让类T 成为内联类,这样您就可以使用通常的import spark.implicits._,它需要引用spark 作为火花会话。例如,import spark.implicits._
    new Product() {
    override def ...
    }
  • def makeDs[T <: product: classtag: encoder dataset string ds.map case t> t -> "hello" } } 仍然无法编译。我不明白。 :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-13
  • 1970-01-01
相关资源
最近更新 更多