等价于getLong的TimestampType / java.sql.Timestamp?

时间:2017-10-06 20:13:30

标签: scala apache-spark apache-spark-sql flatmap

我正在尝试使用scala从火花流数据帧中提取值,其代码如下:

var txs = spark.readStream
  .format("kafka") .option("kafka.bootstrap.servers",KAFKABS)
  .option("subscribe", "txs")
  .load()
txs = txs.selectExpr("CAST(value AS STRING)")

val schema = StructType(Seq(
      StructField("from",StringType,true),
      StructField("to", StringType, true),  
      StructField("timestamp", TimestampType, true),
        StructField("hash", StringType, true),
      StructField("value", StringType, true)
))

txs = txs.selectExpr("cast (value as string) as json")
            .select(from_json($"json", schema).as("data"))
            .select("data.*")
            .selectExpr("from","to","cast(timestamp as timestamp) as timestamp","hash","value") 
val newDataFrame = txs
  .flatMap(row => {
    val to = row.getString(0)
    val from = row.getString(1)
   // val timestamp = row.getTimestamp??

   //do stuff
  })

我想知道Timestamps是否有一个等效的类型get方法?为了增加我的困惑,似乎在我为结构化流定义的SQL类型之间存在某种隐藏映射(至少对我隐藏),以及当我通过{{1}访问它们时变量的实际类型功能。我查看了文档,事实确实如此。根据文件:

  

返回位置i的值。如果值为null,则为null   回。以下是Spark SQL类型与之间的映射   返回类型:

     

BooleanType - > java.lang.Boolean ByteType - > java.lang.Byte的
  ShortType - > java.lang.Short IntegerType - > java.lang.Integer中
  FloatType - > java.lang.Float DoubleType - > java.lang.Double中
  StringType - > String DecimalType - > java.math.BigDecimal中

     

DateType - > java.sql.Date TimestampType - >的java.sql.Timestamp

     

BinaryType - >字节数组ArrayType - > scala.collection.Seq(使用   getList for java.util.List)MapType - > scala.collection.Map(使用   getJavaMap for java.util.Map)StructType - >   org.apache.spark.sql.Row

考虑到这一点,我原本预计这个映射会更正式地作为它实现的接口进入flatMap类,但显然情况并非如此:(似乎在这种情况下) TimestampType / java.sql.Timestamp,我不得不放弃我的时间戳类型的东西?有人请解释为什么我错了!我现在只使用scala和spark 3-4个月了。

-Paul

1 个答案:

答案 0 :(得分:1)

您已正确推断TimestampType列的Scala类型为java.sql.Timestamp

V1.5.0 开始。 org.apache.spark.sql.Row has getTimestamp(i: Int)方法,因此您可以调用它并获得java.sql.Timestamp

val timestamp = row.getTimestamp(1)

即使您使用的是早期版本,也无需放弃此类型,您只需将getAs[T](i: Int)java.sql.Timestamp一起使用即可:

val timestamp = row.getAs[java.sql.Timestamp](2)
// OR:
val timestamp = row.getAs[java.sql.Timestamp]("timestamp")