Почему возникает ошибка «Невозможно найти кодировщик для типа, хранящегося в наборе данных» при кодировании JSON с использованием классов case?

Я написал искровую работу:

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()
  }
}

В IDE, когда я запускаю основную функцию, возникает 2 ошибки:

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]
                                                                  ^

но в Spark Shell я могу запустить это задание без ошибок. в чем проблема?


person Milad Khajavi    schedule 11.01.2016    source источник


Ответы (3)


В сообщении об ошибке говорится, что Encoder не может принять класс case 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.

Переместите объявление класса case за пределы SimpleApp.

person Developer    schedule 11.01.2016
comment
Почему область видимости имеет здесь какое-то значение? Я получаю эту ошибку при использовании REPL. - person JackOrJones; 15.09.2016
comment
Я пытаюсь понять, почему объем класса case имеет значение, если вы можете указать мне на любой ресурс, который я могу прочитать и понять, это будет очень полезно. Довольно новое с неявным scala :( @jacek-laskowski - person Sudev Ambadi; 01.09.2018
comment
Я не думаю, что способен объяснить, почему решение работает именно так. Я смутно припоминаю, что это не имеет ничего общего с имплицитами, которые представляют собой просто механизм для подключения кода и принятия самого кода за первопричину. - person Jacek Laskowski; 01.09.2018

У вас будет та же ошибка, если вы добавите sqlContext.implicits._ и spark.implicits._ в SimpleApp (порядок не имеет значения).

Удаление одного или другого будет решением:

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]

Протестировано с Spark 2.1.0

Самое смешное, что если вы добавите один и тот же имплицит дважды, у вас не будет проблем.

person Paul Leclercq    schedule 28.02.2017

@Милад Хаджави

Определить классы дел Person вне объекта SimpleApp. Также добавьте импорт sqlContext.implicits._ внутрь функции main().

person Santhoshm    schedule 30.08.2018