簡體   English   中英

Generic T as Spark 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM