java.lang.RuntimeException: 不支持的文字类型 class org.joda.time.DateTime

java.lang.RuntimeException: Unsupported literal type class org.joda.time.DateTime

我在一个项目中使用了一个库,这对我来说很新,尽管我在其他项目中使用过它,没有任何问题。

org.joda.time.DateTime

所以我使用 Scala,运行 这个项目是 Databricks 上的一份工作。

scalaVersion := "2.11.12"

根据我目前的调查^^,异常来自的代码如下:

    var lastEndTime = config.getState("some parameters")

    val timespanStart: Long = lastEndTime // last query ending time
    var timespanEnd: Long = (System.currentTimeMillis / 1000) - (60*840) // 14 hours ago

    val start = new DateTime(timespanStart * 1000)
    val end = new DateTime(timespanEnd * 1000)

    val date = DateTime.now()

其中 getState() 函数 returns 1483228800Long 类型值。

编辑:我在构建数据框时使用开始和结束日期进行过滤。我将列(时间跨度类型)与这些值进行比较!

val df2= df
           .where(col("column_name").isNotNull)
           .where(col("column_name") > start &&
                  col("column_name") <= end)

我得到的错误:

ERROR Uncaught throwable from user code: java.lang.RuntimeException: Unsupported literal type class org.joda.time.DateTime 2017-01-01T00:00:00.000Z

我不确定我是否真的理解这是一个错误以及为什么会出现错误,所以非常欢迎各种帮助!!非常感谢您!

这是人们开始使用 Spark 时的常见问题 SQL。 Spark SQL 有自己的 types,如果您想利用 Dataframe API,您需要与它们合作。在您的示例中,您不能使用 Spark Sql 函数(如“col”)直接将 Dataframe 列值与 DateTime 对象进行比较,除非您使用 UDF。

如果您想使用 Spark sql 函数进行比较,您可以查看 this post,您可以在其中找到使用日期和时间戳与 Spark 数据帧的差异。

如果您(出于任何原因)需要使用 Joda,您将不可避免地需要构建您的 UDF:

import org.apache.spark.sql.DataFrame
import org.joda.time.DateTime
import org.joda.time.format.{DateTimeFormat, DateTimeFormatter}

object JodaFormater {
  val formatter: DateTimeFormatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss")
}

object testJoda {

  import org.apache.spark.sql.functions.{udf, col}
  import JodaFormater._

  def your_joda_compare_udf = (start: DateTime) => (end: DateTime) => udf { str =>
    val dt: DateTime = formatter.parseDateTime(str)
    dt.isAfter(start.getMillis) && dt.isBefore(start.getMillis)
  }

  def main(args: Array[String]) : Unit = {

    val start: DateTime = ???
    val end : DateTime = ???

    // Your dataframe with your date as StringType

    val df: DataFrame = ???
    df.where(your_joda_compare_udf(start)(end)(col("your_date")))

  }
}

请注意,使用此实现意味着一些开销(内存和 GC),因为从 StringType 到 Joda DateTime 对象的转换因此您应该尽可能使用 Spark SQL 函数 。在某些 post 中,您可以读到 udfs 是黑盒,因为 Spark 无法优化它们的执行,但有时它们会有所帮助。