簡體   English   中英

Apache Spark 2.0:java.lang.UnsupportedOperationException:找不到java.time.LocalDate的編碼器

[英]Apache Spark 2.0: java.lang.UnsupportedOperationException: No Encoder found for java.time.LocalDate

我正在使用Apache Spark 2.0並為DetaSet創建DetaSet架構的case class 當我試圖根據如何在數據集中存儲自定義對象來定義自定義編碼器 ,對於java.time.LocalDate我得到以下異常:

java.lang.UnsupportedOperationException: No Encoder found for java.time.LocalDate
- field (class: "java.time.LocalDate", name: "callDate")
- root class: "FireService"
at org.apache.spark.sql.catalyst.ScalaReflection$.org$apache$spark$sql$catalyst$ScalaReflection$$serializerFor(ScalaReflection.scala:598)
at org.apache.spark.sql.catalyst.ScalaReflection$$anonfun$9.apply(ScalaReflection.scala:592)
at org.apache.spark.sql.catalyst.ScalaReflection$$anonfun$9.apply(ScalaReflection.scala:583)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
at scala.collection.immutable.List.foreach(List.scala:381)
at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241)
............

以下是代碼:

case class FireService(callNumber: String, callDate: java.time.LocalDate)
implicit val localDateEncoder: org.apache.spark.sql.Encoder[java.time.LocalDate] = org.apache.spark.sql.Encoders.kryo[java.time.LocalDate]

val fireServiceDf = df.map(row => {
val dateFormatter = java.time.format.DateTimeFormatter.ofPattern("MM/dd /yyyy")
FireService(row.getAs[String](0),  java.time.LocalDate.parse(row.getAs[String](4), dateFormatter))
})

我們如何定義第三方api的spark編碼器?

更新

當我為整個案例類創建編碼器時, df.map..將對象映射為二進制,如下所示:

implicit val fireServiceEncoder: org.apache.spark.sql.Encoder[FireService] = org.apache.spark.sql.Encoders.kryo[FireService]

val fireServiceDf = df.map(row => {
 val dateFormatter = java.time.format.DateTimeFormatter.ofPattern("MM/dd/yyyy")
 FireService(row.getAs[String](0), java.time.LocalDate.parse(row.getAs[String](4), dateFormatter))
})

fireServiceDf: org.apache.spark.sql.Dataset[FireService] = [value: binary]

我期待FireService的地圖,但返回地圖的二進制。

正如最后一條評論所說,“如果類包含一個字段條,則需要整個對象的編碼器。” 您需要為FireService本身提供一個隱式編碼器; 否則Spark使用SQLImplicits.newProductEncoder[T <: Product : TypeTag]: Encoder[T]為您構造一個SQLImplicits.newProductEncoder[T <: Product : TypeTag]: Encoder[T] 您可以從類型中看到它不使用字段的任何implicit編碼器參數,因此它不能使用localDateEncoder

可以更改Spark以處理此問題,例如使用Shapeless庫或直接使用宏; 我不知道這是否是未來的計划。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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