java.lang.RuntimeException: неподдерживаемый литеральный тип класса 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() возвращает 1483228800 в качестве значения типа Long.

EDIT: я использую даты начала и окончания в фильтрации при создании фрейма данных. Я сравниваю столбцы (тип timespan) с этими значениями!

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

Ошибка, которую я получаю:

ОШИБКА Uncaught throwable from user code: java.lang.RuntimeException: неподдерживаемый литеральный тип класса org.joda.time.DateTime 2017-01-01T00:00:00.000Z

Я не уверен, что на самом деле понимаю, как и почему это ошибка, поэтому любая помощь более чем приветствуется! Заранее большое спасибо!!


person Eva    schedule 02.07.2019    source источник
comment
Вы используете Dataframe api?   -  person Emiliano Martinez    schedule 02.07.2019
comment
Я не уверен, использую ли я DF API, но я определенно использую фреймы данных и org.apache.spark.sql.SparkSession.   -  person Eva    schedule 02.07.2019
comment
В этом случае отредактируйте свой вопрос и добавьте код DF для лучшего понимания.   -  person Emiliano Martinez    schedule 02.07.2019
comment
Я не уверен, что этот пример кода поможет! :)   -  person Eva    schedule 02.07.2019


Ответы (1)


Это распространенная проблема, когда люди начинают работать со Spark SQL. Spark SQL имеет собственные типы. и вам нужно работать с ними, если вы хотите воспользоваться API Dataframe. В вашем примере вы не можете напрямую сравнивать значение столбца Dataframe с помощью функции Spark Sql, такой как col, с объектом DateTime, если вы не используете UDF.

Если вы хотите провести сравнение с помощью функций Spark sql, вы можете взглянуть на этот сообщение, где вы можете найти различия, используя даты и временные метки с фреймами данных 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 всякий раз, когда это возможно. В некоторых постах можно прочитать, что udfs — это черные ящики, потому что Spark не может оптимизировать их выполнение, но иногда они помогают.

person Emiliano Martinez    schedule 02.07.2019
comment
Спасибо за все усилия, которые вы приложили к этому ответу, теперь я понимаю, что я пытался сделать. Я решил не использовать joda и изменил начало и конец на тип java.sql.Date (и текущая дата исходит из java.time.LocalDateTime)! Теперь все работает, так что еще раз большое спасибо!! :) - person Eva; 02.07.2019