通用t作为火花数据集[t]构造函数



在以下片段中,如果存在tryParquet函数,则可以从Parquet文件加载数据集。如果没有,它将计算,持续并返回提供的数据集计划:

import scala.util.{Try, Success, Failure}
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.Dataset
sealed trait CustomRow
case class MyRow(
  id: Int,
  name: String
) extends CustomRow
val ds: Dataset[MyRow] =
  Seq((1, "foo"),
      (2, "bar"),
      (3, "baz")).toDF("id", "name").as[MyRow]
def tryParquet[T <: CustomRow](session: SparkSession, path: String, target: Dataset[T]): Dataset[T] =
    Try(session.read.parquet(path)) match {
      case Success(df) => df.as[T] // <---- compile error here
      case Failure(_)  => {
        target.write.parquet(path)
        target
      }
    }
val readyDS: Dataset[MyRow] =
    tryParquet(spark, "/path/to/file.parq", ds)

但是,这会在df.as[T]上产生编译错误:

无法找到存储在数据集中的类型的编码器。原始类型(INT,字符串等)和产品类型(案例类)通过导入Spark._

来支持

支持其他类型的支持将在以后的版本中添加。

案例成功(df)=> df.as [t]

可以通过使tryParquet铸造df返回未型DataFrame并让呼叫者施放到所需的构造函数来解决此问题。但是,我们是否希望该类型由函数内部管理?

在类型参数中使用Encoder看起来可能是可能的:

import org.apache.spark.sql.Encoder
def tryParquet[T <: CustomRow: Encoder](...)

这样,编译器可以证明df.as[T]在构造对象时提供编码器。

最新更新