3

사용자 정의 견적서의 transformSchema 메소드의 경우 입력 데이터 프레임의 스키마를 사례 클래스에 정의 된 스키마와 비교할 수 있어야합니다. 일반적으로 아래에 설명 된대로 Generate a Spark StructType/Schema from a case class처럼 수행 할 수 있습니다. 그러나 잘못된 Null 허용이 사용됩니다정확한 null 허용 케이스 클래스의 Spark 스키마

root 
|-- CUSTOMER_ID: integer (nullable = false) 

그리고 경우 클래스 :

case class MySchema(CUSTOMER_ID: Int) 

은 내가 사용하는 비교하려면 :

spark.read.csv().as[MyClass]에 의해 유추 안양의 실제 스키마처럼 보일 수 있습니다

val rawSchema = ScalaReflection.schemaFor[MySchema].dataType.asInstanceOf[StructType] 
    if (!rawSchema.equals(rawDf.schema)) 

불행히도 이것은 항상 false (JA java.Integer 실제로 null이 될 수 있기 때문에) 수동의 경우 클래스에서 유추 새로운 스키마가 true에 널 (NULL)로 설정 될 때 스키마를 만들 때,

root 
|-- CUSTOMER_ID: integer (nullable = true) 

어떻게 nullable = false을 지정할 수 있습니다?

답변

3

아마도 같은 공간에 속하지 않는 것들을 혼합하고있을 것입니다. ML 파이프 라인은 본질적으로 동적이며 정적으로 타입이 지정된 객체를 도입해도 실제로 변경되지 않습니다.

case class MySchema(CUSTOMER_ID: Int) 

CUSTOMER_ID Null을 허용하지있을 것이다 : 클래스에 대한

또한 스키마는 다음과 같이 정의했다. 위와 같이하지 널 (NULL) 사용을 Int을 원하는 경우

case class MySchema(CUSTOMER_ID: Option[Int]) 

과 : 당신이 nullable 필드 Option[Int]을 원하는 경우 말했다되는

scala> import org.apache.spark.sql.catalyst.ScalaReflection.schemaFor 
import org.apache.spark.sql.catalyst.ScalaReflection.schemaFor 

scala> case class MySchema(CUSTOMER_ID: Int) 
defined class MySchema 

scala> schemaFor[MySchema].dataType 
res0: org.apache.spark.sql.types.DataType = StructType(StructField(CUSTOMER_ID,IntegerType,false)) 

그건 : scala.Intjava.lang.Integer와 동일하지 않습니다.

또 다른 문제는 csv의 경우 모든 필드가 정의에 의해 Null 가능하며이 상태는 인코딩 된 Dataset에 의해 "상속"된다는 것입니다.

spark.read.csv(...) 

항상 발생합니다 :

root 
|-- CUSTOMER_ID: integer (nullable = true) 

하고 스키마 불일치를 얻는 이유는 실제로 그래서. 불행히도 csv 또는 json과 같이 null 허용 제한을 적용하지 않는 소스에 대해 nullable 필드를 재정의하는 것은 불가능합니다.

하지 널 (NULL) 스키마를 갖는 것은 당신이 시도 할 수있는 어려운 요구 사항 인 경우 :

spark.createDataFrame(
    spark.read.csv(...).rdd, 
    schemaFor[MySchema].dataType.asInstanceOf[StructType] 
).as[MySchema] 

이 방법을 사용하면 데이터가 실제로 무료 null 것을 알고 경우에만 유효은.null 값은 런타임 예외로 나타납니다.