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',在模式的情況下,我們有'時間:時間戳'。 因此,我們仍然必須將我們的時間字段放入時間戳中,然後再讀取它:/ –