web-dev-qa-db-fra.com

Pourquoi l'erreur "Impossible de trouver l'encodeur pour le type stocké dans un ensemble de données" lors de l'encodage JSON à l'aide des classes de cas?

J'ai écrit spark job:

object SimpleApp {
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("Simple Application").setMaster("local")
    val sc = new SparkContext(conf)
    val ctx = new org.Apache.spark.sql.SQLContext(sc)
    import ctx.implicits._

    case class Person(age: Long, city: String, id: String, lname: String, name: String, sex: String)
    case class Person2(name: String, age: Long, city: String)

    val persons = ctx.read.json("/tmp/persons.json").as[Person]
    persons.printSchema()
  }
}

Dans IDE lorsque j'exécute la fonction principale, 2 erreurs se produisent:

Error:(15, 67) Unable to find encoder for type stored in a Dataset.  Primitive types (Int, String, etc) and Product types (case classes) are supported by importing sqlContext.implicits._  Support for serializing other types will be added in future releases.
    val persons = ctx.read.json("/tmp/persons.json").as[Person]
                                                                  ^

Error:(15, 67) not enough arguments for method as: (implicit evidence$1: org.Apache.spark.sql.Encoder[Person])org.Apache.spark.sql.Dataset[Person].
Unspecified value parameter evidence$1.
    val persons = ctx.read.json("/tmp/persons.json").as[Person]
                                                                  ^

mais dans Spark Shell, je peux exécuter ce travail sans aucune erreur. quel est le problème?

16
Milad Khajavi

Le message d'erreur indique que Encoder ne peut pas prendre la classe de cas Person.

Error:(15, 67) Unable to find encoder for type stored in a Dataset.  Primitive types (Int, String, etc) and Product types (case classes) are supported by importing sqlContext.implicits._  Support for serializing other types will be added in future releases.

Déplacez la déclaration de la classe de cas en dehors de la portée de SimpleApp.

34
Developer

Vous avez la même erreur si vous ajoutez sqlContext.implicits._ et spark.implicits._ dans SimpleApp (l'ordre n'a pas d'importance).

Supprimer l'un ou l'autre sera la solution:

val spark = SparkSession
  .builder()
  .getOrCreate()

val sqlContext = spark.sqlContext
import sqlContext.implicits._ //sqlContext OR spark implicits
//import spark.implicits._ //sqlContext OR spark implicits

case class Person(age: Long, city: String)
val persons = ctx.read.json("/tmp/persons.json").as[Person]

Testé avec Spark 2.1.

Le plus drôle, c'est que si vous ajoutez deux fois le même objet, vous n'aurez aucun problème.

4
Paul Leclercq

@Milad Khajavi

Définissez les classes de cas de personne en dehors de l'objet SimpleApp. Ajoutez également import sqlContext.implicits._ à l'intérieur de la fonction main ().

2
Santhoshm