【问题标题】:Creating Dataframe which uses BigInteger throws scala.MatchError: class java.math.BigInteger (of class java.lang.Class)创建使用 BigInteger 的 Dataframe 会抛出 scala.MatchError: class java.math.BigInteger (of class java.lang.Class)
【发布时间】:2018-08-27 03:51:56
【问题描述】:

Spark 版本:1.3

我有一个要求,我正在处理BigInteger 类型的数据。 Bean 类 (Pojo) 使用很少的 BigInteger 数据类型。解析数据并创建JavaRDD 工作正常,但是在创建以 JavaRDD 和 BeanClass 作为参数的数据帧时,Spark 会抛出以下异常。

scala.MatchError: class java.math.BigInteger (of class java.lang.Class)
        at org.apache.spark.sql.SQLContext$$anonfun$getSchema$1.apply(SQLContext.scala:1182)
        at org.apache.spark.sql.SQLContext$$anonfun$getSchema$1.apply(SQLContext.scala:1181)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
        at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
        at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)
        at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
        at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:108)
        at org.apache.spark.sql.SQLContext.getSchema(SQLContext.scala:1181)
        at org.apache.spark.sql.SQLContext.createDataFrame(SQLContext.scala:419)
        at org.apache.spark.sql.SQLContext.createDataFrame(SQLContext.scala:447)

使用 Spark-Shell 我看到 Scala 能够处理 BigInt

scala> val x = BigInt("190753000000000000000");

x: scala.math.BigInt = 190753000000000000000

我不确定异常的原因是什么。任何帮助将不胜感激。

【问题讨论】:

标签: scala apache-spark apache-spark-sql


【解决方案1】:

根据@zero232 的回答,您的异常可以通过在变量声明中使用BigDecimal 而不是BigInt 来解决:

scala> val x = BigDecimal("190753000000000000000");

【讨论】:

    【解决方案2】:

    您会收到异常,因为 BigInt 不是 Spark DataFrames 支持的数据类型。唯一支持的Big* 类型是BigDecimal

    您可以在 Data Types sectionSpark SQL and DataFrame Guide 中找到支持的类型和映射的完整列表

    【讨论】:

      【解决方案3】:

      可以参考memSQL的BigInt UserDefinedType:

          package com.memsql.spark.connector.dataframe
      
          import org.apache.spark.sql.types._
      
      
          @SQLUserDefinedType(udt = classOf[BigIntUnsignedType])
          class BigIntUnsignedValue(val value: Long) extends Serializable {
            override def toString: String = value.toString
          }
      
          /**
           * Spark SQL [[org.apache.spark.sql.types.UserDefinedType]] for MemSQL's `BIGINT UNSIGNED` column type.
           */
          class BigIntUnsignedType private() extends UserDefinedType[BigIntUnsignedValue] {
            override def sqlType: DataType = LongType
      
            override def serialize(obj: Any): Long = {
              obj match {
                case x: BigIntUnsignedValue => x.value
                case x: String       => x.toLong
                case x: Long         => x
              }
            }
      
            override def deserialize(datum: Any): BigIntUnsignedValue = {
              datum match {
                case x: String => new BigIntUnsignedValue(x.toLong)
                case x: Long => new BigIntUnsignedValue(x)
              }
            }
      
            override def userClass: Class[BigIntUnsignedValue] = classOf[BigIntUnsignedValue]
      
            override def asNullable: BigIntUnsignedType = this
      
            override def typeName: String = "bigint unsigned"
          }
      
          case object BigIntUnsignedType extends BigIntUnsignedType
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 2018-03-05
        • 2022-12-27
        • 2022-09-28
        • 1970-01-01
        相关资源
        最近更新 更多