Я работаю над проектом, в котором использую очень новую для меня библиотеку, хотя я использовал ее в других проектах без каких-либо проблем.
org.joda.time.DateTime
Поэтому я работаю с Скала и запускаю проект как задание на Блоки данных.
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 как значение типа Длинная.
РЕДАКТИРОВАТЬ: я использую даты начала и окончания для фильтрации при построении фрейма данных. Я сравниваю столбцы (тип timespan) с этими значениями!
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
Я не уверен, что на самом деле понимаю, как и почему это ошибка, поэтому любая помощь более чем приветствуется! Заранее большое спасибо!!
Я не уверен, использую ли я DF API, но я определенно использую фреймы данных и org.apache.spark.sql.SparkSession.
В этом случае отредактируйте свой вопрос и добавьте код DF для лучшего понимания.
Я не уверен, что этот пример кода поможет! :)
Это распространенная проблема, когда люди начинают работать со Spark SQL. Spark SQL имеет собственный типы, и вам необходимо работать с ними, если вы хотите воспользоваться преимуществами API Dataframe. В вашем примере вы не можете напрямую сравнивать значение столбца Dataframe с помощью функции Spark Sql, такой как «колонка», с объектом 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 не может оптимизировать их выполнение, но иногда они помогают.
Спасибо за все усилия, которые вы приложили к этому ответу, теперь я понимаю, что я пытался сделать. Я решил не использовать joda и изменил начало и конец на тип java.sql.Date (и текущая дата исходит из java.time.LocalDateTime)! Теперь все работает, так что еще раз большое спасибо!! :)
Вы используете Dataframe api?