1

我在Databricks笔记本星火SQL的斯卡拉API - TimestampType - 无编码器发现org.apache.spark.sql.types.TimestampType

使用的Spark 2.1斯卡拉2.11究竟是什么TimestampType?

TimestampType可以在这里找到了SparkSQL的斯卡拉API

在:

我们从SparkSQL's documentation这是官方的时间戳类型是TimestampType,这显然是对的java.sql.Timestamp别名知道

我们使用模式和数据集API

时当解析{"time":1469501297,"action":"Open"}from the Databricks' Scala Structured Streaming example

有差异

使用JSON模式 - >确定(我不喜欢用高雅的数据集API):

val jsonSchema = new StructType().add("time", TimestampType).add("action", StringType) 

val staticInputDF = 
    spark 
    .read 
    .schema(jsonSchema) 
    .json(inputPath) 

使用DataSet API - > KO:无编码器发现TimestampType

从DBFS上databricks读取事件时,创建事件类

import org.apache.spark.sql.types._ 
case class Event(action: String, time: TimestampType) 
--> defined class Event 

错误。

注意:在使用java.sql.Timestamp的类型 “时间”

val path = "/databricks-datasets/structured-streaming/events/" 
val events = spark.read.json(path).as[Event] 

错误消息

java.lang.UnsupportedOperationException: No Encoder found for org.apache.spark.sql.types.TimestampType 
- field (class: "org.apache.spark.sql.types.TimestampType", name: "time") 
- root class: 

回答

1

结合模式读取方法.schema(jsonSchema)as[Type]方法包含类型java.sql.Timestamp将解决此问题。这个想法是从结构化流读取文档Creating streaming DataFrames and streaming Datasets

这些例子生成数据框的模式在编译期进行检查流DataFrames是无类型,意味着 ,只有 检查后在运行时提交查询。一些操作,如 地图,flatMap等需要在编译时知道类型。要做 那些,您可以使用与静态DataFrame相同的方法将这些非类型化的流式数据帧转换为输入流式数据集 。

val path = "/databricks-datasets/structured-streaming/events/" 

val jsonSchema = new StructType().add("time", TimestampType).add("action", StringType) 

case class Event(action: String, time: java.sql.Timestamp) 

val staticInputDS = 
    spark 
    .read 
    .schema(jsonSchema) 
    .json(path) 
    .as[Event] 

staticInputDF.printSchema 

将输出:

root 
|-- time: timestamp (nullable = true) 
|-- action: string (nullable = true) 
2

TimestampType当我们没有得到错误不是一个别名java.sql.Timestamp,而是Spark内部使用的时间戳类型的表示。一般来说,你不想在代码中使用TimestampType。这个想法是,java.sql.Timestamp由星火SQL原生支持,所以你可以如下定义您事件类:

case class Event(action: String, time: java.sql.Timestamp) 

内部,星火然后将使用TimestampType在运行时的值的类型进行建模,编译和优化时您的查询,但这不是您大多数时间感兴趣的内容。

+0

随着'java.sql.Timestamp'如果我们使用dataset.printSchema我们有'时间:long',在模式的情况下,我们有'时间:时间戳'。 因此,我们仍然必须将我们的时间字段放入时间戳中,然后再读取它:/ –