사용자 정의 케이스 클래스의 데이터 세트를 만들 때 "데이터 세트에 저장된 유형에 대한 인코더를 찾을 수 없음"이 나타나는 이유는 무엇입니까?
Scala 2.11.8이 포함 된 Spark 2.0 (최종). 다음 매우 간단한 코드는 컴파일 오류를 생성합니다.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
는 Encoders
저장 될 데이터 유형이 필요 합니다. 일반적인 유형 (원자, 제품 유형)의 경우 미리 정의 된 여러 인코더가 있지만 SparkSession.implicits
작동하려면 먼저 다음에서 가져와야 합니다.
val sparkSession: SparkSession = ???
import sparkSession.implicits._
val dataset = sparkSession.createDataset(dataList)
또는 명시 적으로 직접 제공 할 수 있습니다.
import org.apache.spark.sql.{Encoder, Encoders}
val dataset = sparkSession.createDataset(dataList)(Encoders.product[SimpleTuple])
또는 암시 적
implicit val enc: Encoder[SimpleTuple] = Encoders.product[SimpleTuple]
val dataset = sparkSession.createDataset(dataList)
Encoder
저장된 유형에 대해.
주 Enocders
사전 정의도 다수 제공 Encoders
원자 유형 및 Encoders
복잡한 것들에 대해, 도출있다 ExpressionEncoder
.
추가 읽기 :
- 기본 제공 인코더에 포함되지 않는 사용자 지정 개체의 경우 데이터 집합에 사용자 지정 개체를 저장하는 방법을 참조하세요 .
- 들어
Row
객체는 제공해야Encoder
같이 명시 적으로 인코더 오류 업데이트 된 행 dataframe 행을지도하는 동안
다른 사용자의 경우 (귀하의 것이 맞습니다) 범위 case class
밖에서 정의 되는 것도 중요합니다 object
. 그래서:
실패 :
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)
}
}
암시 적을 추가하고 여전히 동일한 오류로 실패합니다.
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)
}
}
공장:
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)
}
}
관련 버그는 다음과 같습니다. https://issues.apache.org/jira/browse/SPARK-13540 이므로 Spark 2의 다음 릴리스에서 수정되기를 바랍니다.
(편집 : 버그 수정이 실제로 Spark 2.0.0에있는 것 같습니다 ... 그래서 이것이 왜 여전히 실패하는지 잘 모르겠습니다).
I'd clarify with an answer to my own question, that if the goal is to define a simple literal SparkData frame, rather than use Scala tuples and implicit conversion, the simpler route is to use the Spark API directly like this:
import org.apache.spark.sql._
import org.apache.spark.sql.types._
import scala.collection.JavaConverters._
val simpleSchema = StructType(
StructField("a", StringType) ::
StructField("b", IntegerType) ::
StructField("c", IntegerType) ::
StructField("d", IntegerType) ::
StructField("e", IntegerType) :: Nil)
val data = List(
Row("001", 1, 0, 3, 4),
Row("001", 3, 4, 1, 7),
Row("001", null, 0, 6, 4),
Row("003", 1, 4, 5, 7),
Row("003", 5, 4, null, 2),
Row("003", 4, null, 9, 2),
Row("003", 2, 3, 0, 1)
)
val df = spark.createDataFrame(data.asJava, simpleSchema)
ReferenceURL : https://stackoverflow.com/questions/38664972/why-is-unable-to-find-encoder-for-type-stored-in-a-dataset-when-creating-a-dat
'programing' 카테고리의 다른 글
쓰기 가능한 스트림을 구현하는 방법 (0) | 2021.01.18 |
---|---|
경로가 변경 될 때 Angular UI Bootstrap 모달을 자동으로 닫는 방법이 있습니까? (0) | 2021.01.18 |
VS 2017 메타 데이터 파일 '.dll을 찾을 수 없습니다. (0) | 2021.01.18 |
XML을 C #의 개체로 역 직렬화 (0) | 2021.01.18 |
Netbeans에 사용자 정의 파일 확장자 추가 (0) | 2021.01.18 |