spark读取模式类型以创建插入语句

时间:2018-04-23 14:20:24

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

root
|-- s_time: string (nullable = false)
|-- c_time: string (nullable = false)
|-- id: string (nullable = true)
|-- sesh: string (nullable = true)
|-- event_data: struct (nullable = false)
|    |-- reason: string (nullable = true)
|    |-- status: long (nullable = false)
|-- ip: string (nullable = true)
|-- tags: array (nullable = false)
|    |-- element: string (containsNull = false)
|-- xxxx: string (nullable = false)
|-- yyyy: string (nullable = false)
|-- app: string (nullable = false)

我有以下动态创建的架构。然后我创建一个空数据框,我打算从中动态模拟一个insert语句。 一个硬编码的例子是:

INSERT INTO temp VALUES ('a','a','a','a',STRUCT('a',9), 'a',ARRAY('a'),'a','a','a')

所以我将我的模式转换为dtypes,这样我就可以“在理论上”依赖于它的类型。构建上面的字符串。

schema.dtypes.foreach {  f =>
  val fName = f._1
  val fType = f._2

  fType match {
  case "StringType" =>
  println(fName)

  case "StructType" =>
  println(s"LOOOK HEREEEREEEEEEEE")

  case "ArrayType" =>
  println("ARRAYSSSS")

  case _ => None
}

问题是当我搜索“StructType”或“ArrayType”时,我永远无法匹配。当我打印出fType时,我会看到类似的内容:

StructType(StructField(reason,StringType,true), StructField(status,LongType,false))

1 个答案:

答案 0 :(得分:0)

我没有找到如何将架构转换为dtypes的方法。但是,您可以循环使用字段并为每行使用dataType。

这对我有用:

val schema = StructType(
StructField("s_time", StringType, true) ::
  StructField("c_time", StringType, false) ::
  StructField("id", StringType, false) ::
  StructField("sesh", StringType, false) ::
  StructField("event_data", StructType(
    Seq(
      StructField("reason", StringType, false),
      StructField("status", LongType, false)
    )
  ), false) ::
  StructField("ip", LongType, false) ::
  StructField("tags", ArrayType(StringType), false) ::
  StructField("xxxx", LongType, false) ::
  StructField("yyyy", LongType, false) ::
  StructField("app", LongType, false) :: Nil)

schema.fields.foreach { f =>
  val fName = f.name
  val fType = f.dataType.toString
  fType match {
    case "StringType" =>
      println(fName)
    case s if s.startsWith("Struct") =>
      println(s+"LOOOK HEREEEREEEEEEEE")
    case s if s.startsWith("ArrayType") =>
      println("ARRAYSSSS")
    case _ => None
  }
}