![](/img/trans.png)
[英]Scala Spark function with generic Dataset[T] argument and also returns Dataset[T]?
[英]Generic T as Spark Dataset[T] constructor
在下面的代碼片段中, 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]
上產生編譯錯誤:
無法找到存儲在數據集中的類型的編碼器。 導入spark.implicits._支持原始類型(Int,String等)和產品類型(case類)。
將來的版本中將添加對序列化其他類型的支持。
案例成功(df)=> df.as [T]
通過使tryParquet
cast df
返回一個無類型的DataFrame
並讓調用者DataFrame
轉換為所需的構造函數,可以避免這個問題。 但是,在我們希望函數在內部管理類型的情況下是否有任何解決方案?
通過在type參數中使用Encoder
看起來是可能的:
import org.apache.spark.sql.Encoder
def tryParquet[T <: CustomRow: Encoder](...)
這樣編譯器就可以證明df.as[T]
在構造對象時提供了一個編碼器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.