unsupportedOperationException Ошибка преобразования строки в DateTime с использованием времени Joda

Я преобразовываю строку в поле даты и времени с использованием библиотек joda.time.Datetime, но она выдает неподдерживаемое исключение. Вот код основного класса:

//create new var with input data without header
var inputDataWithoutHeader: RDD[String] = dropHeader(inputFile)
var inputDF1 = inputDataWithoutHeader.map(_.split(",")).map{p =>
val dateYMD: DateTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").parseDateTime(p(8))
testData(dateYMD)}.toDF().show()

p (8) - столбец с типом данных datetime, определенным в классе testData, а данные CSV для столбца имеют значение, например 2013-02-17 00:00:00.

Вот класс testData:

case class testData(StartDate: DateTime) { }

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

Исключение в теме "главная"

java.lang.UnsupportedOperationException: Schema for type org.joda.time.DateTime is not supported
    at org.apache.spark.sql.catalyst.ScalaReflection$class.schemaFor(ScalaReflection.scala:153)
    at org.apache.spark.sql.catalyst.ScalaReflection$.schemaFor(ScalaReflection.scala:29)
    at org.apache.spark.sql.catalyst.ScalaReflection$$anonfun$schemaFor$1.apply(ScalaReflection.scala:128)
    at org.apache.spark.sql.catalyst.ScalaReflection$$anonfun$schemaFor$1.apply(ScalaReflection.scala:126)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    at org.apache.spark.sql.catalyst.ScalaReflection$class.schemaFor(ScalaReflection.scala:126)
    at org.apache.spark.sql.catalyst.ScalaReflection$.schemaFor(ScalaReflection.scala:29)
    at org.apache.spark.sql.catalyst.ScalaReflection$class.schemaFor(ScalaReflection.scala:64)
    at org.apache.spark.sql.catalyst.ScalaReflection$.schemaFor(ScalaReflection.scala:29)
    at org.apache.spark.sql.SQLContext.createDataFrame(SQLContext.scala:361)
    at org.apache.spark.sql.SQLImplicits.rddToDataFrameHolder(SQLImplicits.scala:47)
    at com.projs.poc.spark.ml.ProcessCSV$delayedInit$body.apply(ProcessCSV.scala:37)

2 ответа

Решение
  1. Как вы можете прочитать в официальной документации, даты в Spark SQL представлены с использованием java.sql.Timestamp, Если вы хотите использовать время Joda, вы должны преобразовать вывод в правильный тип

  2. SparkSQL может легко обрабатывать стандартные форматы даты, используя приведение типов:

    sc.parallelize(Seq(Tuple1("2016-01-11 00:01:02")))
      .toDF("dt")
      .select($"dt".cast("timestamp"))
    

Схема Scala Spark не поддерживает дату и время явно. Вы можете изучить другие варианты. Они есть:

1) Преобразуйте дату и время в миллисекунды, и вы можете поддерживать их в длинном формате.
2) Преобразование даты и времени в формате UnixTime (Java) /questions/27807940/format-timestamptype-v-iskre-dataframe-scala/27807957#27807957
3) Преобразование даты и времени в строку. вы можете вернуться к joda datetime в любой момент, используя DateTime.parse("stringdatetime").
4) Если вы все еще хотите сохранить joda datetime в схеме scala, вы можете преобразовать свой фрейм данных в последовательность

dataframe.rdd.map(r =>DateTime.parse(r(0).toString()).collect().toSeq

Спасибо zero323 за решение. Я использовал java.sql.Timestamp и вот код, который я изменил

val dateYMD: java.sql.Timestamp = new java.sql.Timestamp(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").parseDateTime(p(8)).getMillis)
testData(dateYMD)}.toDF().show()

и изменил мой класс на

case class testData(GamingDate: java.sql.Timestamp) { }
Другие вопросы по тегам