Spark 2.0 (final) avec Scala 2.11.8. Le code super simple suivant génère l'erreur de compilation Error:(17, 45) Unable to find encoder for type stored in a Dataset. Primitive types (Int, String, etc) and Product types (case classes) are supported by importing spark.implicits._ Support for serializing other types will be added in future releases.
import org.Apache.spark.sql.SparkSession
case class SimpleTuple(id: Int, desc: String)
object DatasetTest {
val dataList = List(
SimpleTuple(5, "abc"),
SimpleTuple(6, "bcd")
)
def main(args: Array[String]): Unit = {
val sparkSession = SparkSession.builder.
master("local")
.appName("example")
.getOrCreate()
val dataset = sparkSession.createDataset(dataList)
}
}
Spark Datasets
nécessite Encoders
pour le type de données sur le point d'être stocké. Pour les types courants (atomes, types de produits), il existe un certain nombre de codeurs prédéfinis mais vous devez d'abord les importer de SparkSession.implicits
pour le faire fonctionner:
val sparkSession: SparkSession = ???
import sparkSession.implicits._
val dataset = sparkSession.createDataset(dataList)
Sinon, vous pouvez fournir directement un formulaire explicite
import org.Apache.spark.sql.{Encoder, Encoders}
val dataset = sparkSession.createDataset(dataList)(Encoders.product[SimpleTuple])
ou implicite
implicit val enc: Encoder[SimpleTuple] = Encoders.product[SimpleTuple]
val dataset = sparkSession.createDataset(dataList)
Encoder
pour le type stocké.
Notez que Enocders
fournit également un certain nombre de Encoders
prédéfinis pour les types atomiques et que Encoders
pour les complexes, peuvent être dérivés avec ExpressionEncoder
=.
Lectures complémentaires:
Row
, vous devez fournir Encoder
explicitement comme indiqué dans erreur du codeur lors de la tentative de mappage de la ligne dataframe sur la ligne mise à jourPour les autres utilisateurs (le vôtre est correct), notez qu'il est également important que le case class
est défini en dehors de la portée de object
. Alors:
Échoue:
object DatasetTest {
case class SimpleTuple(id: Int, desc: String)
val dataList = List(
SimpleTuple(5, "abc"),
SimpleTuple(6, "bcd")
)
def main(args: Array[String]): Unit = {
val sparkSession = SparkSession.builder
.master("local")
.appName("example")
.getOrCreate()
val dataset = sparkSession.createDataset(dataList)
}
}
Ajouter les implicites, échoue toujours avec la même erreur:
object DatasetTest {
case class SimpleTuple(id: Int, desc: String)
val dataList = List(
SimpleTuple(5, "abc"),
SimpleTuple(6, "bcd")
)
def main(args: Array[String]): Unit = {
val sparkSession = SparkSession.builder
.master("local")
.appName("example")
.getOrCreate()
import sparkSession.implicits._
val dataset = sparkSession.createDataset(dataList)
}
}
Travaux:
case class SimpleTuple(id: Int, desc: String)
object DatasetTest {
val dataList = List(
SimpleTuple(5, "abc"),
SimpleTuple(6, "bcd")
)
def main(args: Array[String]): Unit = {
val sparkSession = SparkSession.builder
.master("local")
.appName("example")
.getOrCreate()
import sparkSession.implicits._
val dataset = sparkSession.createDataset(dataList)
}
}
Voici le bogue pertinent: https://issues.Apache.org/jira/browse/SPARK-1354 , donc, espérons-le, il sera corrigé dans la prochaine version de Spark = 2.
(Edit: on dirait que ce correctif est en fait dans Spark 2.0.0 ... Donc je ne suis pas sûr de savoir pourquoi cela échoue encore)).