Формат TimestampType в искре DataFrame- Scala
Хотя я пытаюсь преобразовать строковое поле в TimestampType в Spark DataFrame, выходное значение поступает с точностью до микросекунды (yyyy-MM-dd HH:mm:ss.S
). Но мне нужен формат, чтобы быть yyyy-MM-dd HH:mm:ss
т.е. без учета микросекундной точности. Кроме того, я хочу сохранить это как поле метки времени при записи в файл паркета. Таким образом, тип данных моего поля должен быть меткой времени формата yyyy-MM-dd HH:mm:ss
Я пытался использовать TimestampType как
col("column_A").cast(TimestampType)
or
col("column_A").cast("timestamp")
бросить поле на отметку времени. Они способны приводить поле к метке времени, но с точностью до микросекунды.
Может ли кто-нибудь помочь в сохранении типа метки времени в файл паркета с требуемой спецификацией формата.
РЕДАКТИРОВАТЬ
Входные данные:
val a = sc.parallelize(List(("a", "2017-01-01 12:02:00.0"), ("b", "2017-02-01 11:22:30"))).toDF("cola", "colb")
scala> a.withColumn("datetime", date_format(col("colb"), "yyyy-MM-dd HH:mm:ss")).show(false)
+----+---------------------+-------------------+
|cola|colb |datetime |
+----+---------------------+-------------------+
|a |2017-01-01 12:02:00.0|2017-01-01 12:02:00|
|b |2017-02-01 11:22:30 |2017-02-01 11:22:30|
+----+---------------------+-------------------+
scala> a.withColumn("datetime", date_format(col("colb"), "yyyy-MM-dd HH:mm:ss")).printSchema
root
|-- cola: string (nullable = true)
|-- colb: string (nullable = true)
|-- datetime: string (nullable = true)
Выше мы получаем правильный формат метки времени, но когда мы печатаем Схему, поле datetime имеет тип String, но мне нужен тип метки времени здесь.
Теперь, если я попытаюсь привести поле к метке времени, для формата будет задана точность с точностью до микросекунды, что не предусмотрено.
scala> import org.apache.spark.sql.types._
import org.apache.spark.sql.types._
scala> val a = sc.parallelize(List(("a", "2017-01-01 12:02:00.0"), ("b", "2017-02-01 11:22:30"))).toDF("cola", "colb")
a: org.apache.spark.sql.DataFrame = [cola: string, colb: string]
scala> a.withColumn("datetime", date_format(col("colb").cast(TimestampType), "yyyy-MM-dd HH:mm:ss").cast(TimestampType)).show(false)
+----+---------------------+---------------------+
|cola|colb |datetime |
+----+---------------------+---------------------+
|a |2017-01-01 12:02:00.0|2017-01-01 12:02:00.0|
|b |2017-02-01 11:22:30 |2017-02-01 11:22:30.0|
+----+---------------------+---------------------+
scala> a.withColumn("datetime", date_format(col("colb").cast(TimestampType), "yyyy-MM-dd HH:mm:ss").cast(TimestampType)).printSchema
root
|-- cola: string (nullable = true)
|-- colb: string (nullable = true)
|-- datetime: timestamp (nullable = true)
Я ожидаю, что формат будет в yyyy-MM-dd HH:mm:ss
а также тип данных поля timestamp
заранее спасибо
2 ответа
Я думаю, что вам не хватает, что поля timestamp / datetime НЕ имеют читаемых форматов в собственном хранилище. Формат - float, или INT96, или какой-то такой, в зависимости от базы данных. Форматирование даты и времени для удобочитаемости всегда было проблемой отчетности (IE, выполняемый инструментом, подготавливающим данные для отображения), поэтому вы заметили, что когда вы указали формат строки для даты, чтобы она правильно преобразовала ее для хранения как строка База данных (искра) хранит только то, что ей нужно, чтобы точно знать, каково значение времени.
Вы можете указать, что значение временной метки не имеет миллисекунд, т.е. IE, значение миллисекунды равно 0, но не то, что оно не должно отображать миллисекунды.
Это было бы похоже на указание поведения округления в числовом столбце (также проблема отчетности).
Вы можете использовать unix_timestamp, чтобы преобразовать строковое время даты в отметку времени.
unix_timestamp(Column s, String p)
Преобразуйте временную строку с данным шаблоном (см. [ http://docs.oracle.com/javase/tutorial/i18n/format/simpleDateFormat.html ]) в метку времени Unix (в секундах), в случае неудачи верните ноль.
val format = "yyyy-MM-dd HH:mm:ss"
dataframe.withColumn("column_A", unix_timestamp($"date", format))
Надеюсь это поможет!