我正在尝试在spark之上构建一个框架,可以自动创建从数据存储到磁盘的数据集。我想做的事情的一个例子是:
var sparkSession: SparkSession = _ // initialized elsewhere
def generateDataset[T <: Product : TypeTag](path: Path): Dataset[T] = {
val df: DataFrame = generateDataFrameFromPath(path)
import sparkSession.implicits._
df.as[T]
}
效果很好。我遇到的问题是尝试将其扩展到Dataframe
和其他可以生成隐式编码器的类(如String
或Int
)。我试图做这样的事情:
var sparkSession: SparkSession = _ // initialized elsewhere
def generateDataset[T : TypeTag](path: Path): Dataset[T] = {
val df: DataFrame = generateDataFrameFromPath(path)
typeOf[T] match {
case t if t =:= typeOf[Row] => df
case t if t <:< typeOf[Product] =>
import sparkSession.implicits._
df.as[T]
}
}
但是,当我们调用T
时,即使我们知道Product
是.as[T]
的子类,编译器也不喜欢这样。
我知道标准方法是使用Encoder
上下文绑定/隐式,但是我的调用代码在获取数据之前不知道sparkSession
。
有没有办法在没有调用者生成编码器的情况下使其工作?
答案 0 :(得分:0)
尝试生成编码:
def generateDataset[T : TypeTag](path: Path) = {
val df: DataFrame = generateDataFrameFromPath(path)
typeOf[T] match {
case t if t =:= typeOf[Row] => df
case t if t <:< typeOf[Product] =>
implicit val enc: org.apache.spark.sql.Encoder[T] =
org.apache.spark.sql.catalyst.encoders.ExpressionEncoder()
df.as[T]
}
}