java.lang.RuntimeException: неподдерживаемый литеральный тип класса org.joda.time.DateTime - PullRequest
0 голосов
/ 02 июля 2019

Я работаю над проектом, в котором я использую библиотеку, которая является для меня очень новой, хотя я использовал ее в других проектах без каких-либо проблем.

org.joda.time.DateTime

Поэтому я работаю с Scala и запускаю проект как задание на Блоки данных .

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 type type.

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

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

Я получаю сообщение об ошибке:

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

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

1 Ответ

5 голосов
/ 02 июля 2019

Это распространенная проблема, когда люди начинают работать с 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")))

  }
}

Обратите внимание, что использование этой реализации подразумевает некоторые накладные расходы (память и сборщик мусора), посколькупреобразование из StringType в объект Joda DateTime, поэтому вы должны использовать функции Spark SQL всякий раз, когда можете .В некоторых сообщениях вы можете прочитать, что udf - это черные ящики, потому что Spark не может оптимизировать их выполнение, но иногда они помогают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...