我正在尝试将Scala中的表达式转换为工作代码,该表达式将作为String保存在数据库中。
我尝试了Reflect Toolbox,Groovy等。但是我似乎无法实现我所需要的。
这是我尝试过的:
import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
val toolbox = currentMirror.mkToolBox()
val code1 = q"""StructType(StructField(id,IntegerType,true), StructField(name,StringType,true), StructField(tstamp,TimestampType,true), StructField(date,DateType,true))"""
val sType = toolbox.compile(code1)().asInstanceOf[StructType]
我需要使用 sType 实例将customSchema传递到csv文件以创建数据帧,但似乎失败。
有什么方法可以获取StructType的字符串表达式以转换为实际的StructType实例吗?任何帮助将不胜感激。
答案 0 :(得分:3)
如果StructType来自Spark,而您只想将String转换为StructType,则不需要反射。您可以尝试以下方法:
import org.apache.spark.sql.catalyst.parser.LegacyTypeStringParser
import org.apache.spark.sql.types.{DataType, StructType}
import scala.util.Try
def fromString(raw: String): StructType =
Try(DataType.fromJson(raw)).getOrElse(LegacyTypeStringParser.parse(raw)) match {
case t: StructType => t
case _ => throw new RuntimeException(s"Failed parsing: $raw")
}
val code1 =
"""StructType(Array(StructField(id,IntegerType,true), StructField(name,StringType,true), StructField(tstamp,TimestampType,true), StructField(date,DateType,true)))"""
fromString(code1) // res0: org.apache.spark.sql.types.StructType
代码取自Spark中的org.apache.spark.sql.types.StructType
伴随对象。您不能直接使用它,因为它在私人包装中。而且,它使用LegacyTypeStringParser
,所以我不确定这对生产代码是否足够。
答案 1 :(得分:3)
您在准引号内的代码必须是有效的Scala语法,因此您需要为字符串提供引号。您还需要提供所有必要的导入。这有效:
fileprivate func fetchData() {
if self.movieDays != nil
{
self.movieDays.removeAll()
self.headerMovies.removeAll()
}
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
Service.shared.fetchMoviesBySchedule { (movieDays, err) in
if let err = err {
print("Failed to fetch movies", err)
return
}
self.movieDays = movieDays?.data
dispatchGroup.leave()
}
dispatchGroup.enter()
Service.shared.fetchFeaturedMovies { (movies, err) in
if let err = err {
print("Failed to fetch featured movies", err)
return
}
self.headerMovies = movies?.data ?? []
dispatchGroup.leave()
}
dispatchGroup.notify(queue: .main) {
print("complete dispatch")
self.collectionView.reloadData()
self.collectionView.refreshControl?.endRefreshing()
}
}
但是也许不是尝试重新编译代码,而是应考虑以其他方式将结构类型序列化(也许是JSON?)。