从列数组动态生成模式

时间:2019-03-26 13:52:13

标签: scala apache-spark

我有一个列列表,通过使用这些列准备了架构

代码:

SELECT   Max(f1), 
         Max(f2), datepart(hh,timestamp), convert(date,timestamp) 
FROM     TABLE 
WHERE    datepart(hh,timestamp)%4 = 0 
AND timestamp>='2019/3/26 12:00:01' 
AND      timestamp<='2019/3/26 16:00:01'
GROUP BY datepart(hh,timestamp), convert(date,timestamp)
ORDER BY convert(date,timestamp) asc

然后将架构准备为

import  org.apache.spark.sql.types._
val fields = Array("col1", "col2", "col3", "col4", "col5", "col6")
val dynSchema = StructType( fields.map( field =>
       new StructField(field, StringType, true, null) ) )

但是当我尝试使用上述架构从json文件中读取数据时,我得到了StructType(StructField(col1,StringType,true), StructField(col2,StringType,true), StructField(col3,StringType,true), StructField(col4,StringType,true), StructField(col5,StringType,true), StructField(col6,StringType,true))

NullPointerException

但是如果我将数组添加到StructType,它就可以工作。 请帮助我生成动态模式。

编辑:如果我使用上述字段创建架构,则可以从json读取数据。

// reading the data
spark.read.schema(dynSchema).json("./file/path/*.json")

1 个答案:

答案 0 :(得分:2)

只需从创建StructField删除null参数,如下所示:

val dynSchema = StructType( fields.map( field =>
     new StructField(field, StringType, true)))

最后一个参数用于定义有关列的元数据。其默认值不是null,而是Metadata.empty。有关更多详细信息,请参见the source code。在源代码中,他们假定它不能为null,并在不进行任何检查的情况下调用该方法。这就是为什么您获得NullPointerException的原因。