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?
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
.
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.
@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 ().