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

时间:2019-07-02 09:17:08

标签: scala datetime jodatime databricks runtimeexception

我在一个使用库的项目上工作,这对我来说是很新的,尽管我在其他项目中使用它也没有任何问题。

  

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()函数返回1483228800 作为 Long 类型值。

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

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

我得到的错误:

  

ERROR无法从用户代码java.lang.RuntimeException抛出:   不支持的文字类型类org.joda.time.DateTime   2017-01-01T00:00:00.000Z

我不确定我是否真正理解这是怎么回事以及为什么会出错,因此,每种帮助都是值得欢迎的!!提前非常感谢您!!

1 个答案:

答案 0 :(得分:5)

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

如果您想使用Spark sql函数进行比较,可以看看this帖子,您可以在其中使用带有日期和时间戳的Spark Dataframes找到差异。

如果(出于任何原因)需要使用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函数。在某些帖子中,您可以看到udfs是黑匣子,因为Spark无法优化其执行,但有时它们会有所帮助。