将字符串表达式转换为实际工作实例表达式
Convert String expression to actual working instance expression
我正在尝试将 Scala 中作为字符串保存在数据库中的表达式转换回工作代码。
我试过 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 实例吗?任何帮助将不胜感激。
如果 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
,所以我不确定这是否足以用于生产代码。
您在准引号内的代码必须是有效的 Scala 语法,因此您需要为字符串提供引号。您还需要提供所有必要的导入。这有效:
val toolbox = currentMirror.mkToolBox()
val code1 =
q"""
//we need to import all sql types
import org.apache.spark.sql.types._
StructType(
//StructType needs list
List(
//name arguments need to be in proper quotes
StructField("id",IntegerType,true),
StructField("name",StringType,true),
StructField("tstamp",TimestampType,true),
StructField("date",DateType,true)
)
)
"""
val sType = toolbox.compile(code1)().asInstanceOf[StructType]
println(sType)
但也许您不应该尝试重新编译代码,而应该考虑其他替代方案,例如以某种方式序列化结构类型(也许 JSON?)。
我正在尝试将 Scala 中作为字符串保存在数据库中的表达式转换回工作代码。
我试过 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 实例吗?任何帮助将不胜感激。
如果 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
,所以我不确定这是否足以用于生产代码。
您在准引号内的代码必须是有效的 Scala 语法,因此您需要为字符串提供引号。您还需要提供所有必要的导入。这有效:
val toolbox = currentMirror.mkToolBox()
val code1 =
q"""
//we need to import all sql types
import org.apache.spark.sql.types._
StructType(
//StructType needs list
List(
//name arguments need to be in proper quotes
StructField("id",IntegerType,true),
StructField("name",StringType,true),
StructField("tstamp",TimestampType,true),
StructField("date",DateType,true)
)
)
"""
val sType = toolbox.compile(code1)().asInstanceOf[StructType]
println(sType)
但也许您不应该尝试重新编译代码,而应该考虑其他替代方案,例如以某种方式序列化结构类型(也许 JSON?)。