带有转义字段名称的 Scala 案例类在 Spark Catalyst 代码生成期间引发错误
Posted
技术标签:
【中文标题】带有转义字段名称的 Scala 案例类在 Spark Catalyst 代码生成期间引发错误【英文标题】:Scala case class with escaped field name throws error during Spark Catalyst code generation 【发布时间】:2019-09-06 14:54:33 【问题描述】:我有一个带有转义字段名称的案例类,例如:
case class Buyer(`52_week`: String, `26_week`: String,... other fields)
然后我创建这个类的一个实例并传递给 Spark DataFrame,如下所示:
val expected = spark.createDataFrame(sc.parallelize(List(buyer1, buyer2)))
当我尝试保存它时:
expected.write.mode(SaveMode.Append).format("hive").partitionBy("load_date").saveAsTable(tableName)
我得到以下异常:
Caused by: org.codehaus.commons.compiler.CompileException: File 'generated.java', Line 476, Column 15: failed to compile: org.codehaus.commons.compiler.CompileException: File 'generated.java', Line 476, Column 15: Expression "funcResult15 = value65" is not a type
第 476 行是:
/* 475 */ Object funcResult15 = null;
/* 476 */ funcResult15 = value65.52_week();
所以看来我需要以某种方式告诉 Catalyst codegen 转义这些字段。
有没有办法解决这个问题或至少有一些解决方法?
我使用的是 Apache Spark 2.2.0。
【问题讨论】:
是什么让您在案例类中使用此类字段名称? @GoodDok 好吧,那段代码是在我之前编写的 你能以某种方式解决这个问题吗? 【参考方案1】:我建议你创建一个不同的case class
,用一个构造函数从旧的对象中构建一个对象:
case class BuyerRenamed(week_52: String, week_26: String,... other fields)
object BuyerRenamed
def apply(buyer: Buyer): BuyerRenamed =
BuyerRenamed(buyer.`52_week`, buyer.`26_week`, ...)
然后使用带有数据框的新案例类,这将解决 Catalyst 的问题,因为字段将被命名为 value65.week_52()
,这是对方法的适当命名。
也许您会想要添加隐式转换以使代码更清晰。
从长远来看,我建议您重构现有代码以摆脱这种命名,这可能会导致各种突发错误,尤其是当您以某种方式与自动代码生成相关时。
【讨论】:
我不确定我是否理解答案,因为我有一个名为 52_week 的列的 Hive 表,如果会有一个名为 week_52 的案例类,它们在插入 BuyerRenamed 期间将如何匹配? 好吧,如果 Hive 架构也稳定,则可以选择在保存字段之前重命名字段,例如df.select(col("week_52").as("`52_week`"), other columns ...)
。【参考方案2】:
我所做的是将购买者类转换为元组,并明确说明要使用哪些列名。
换句话说,我通过选择不同的路径来绕过代码生成。
代码 sn-p 如下所示:
val expected = spark.createDataFrame(sc.parallelize(List(buyer1, buyer2).map(b => Brand.unapply(b).get))).toDF(extractFieldNames[Buyer]:_*)
extractFieldNames 在哪里:
def extractFieldNames[T<:Product](implicit m: Manifest[T]): Array[String] =
m.erasure.getDeclaredFields.map(_.getName)
【讨论】:
以上是关于带有转义字段名称的 Scala 案例类在 Spark Catalyst 代码生成期间引发错误的主要内容,如果未能解决你的问题,请参考以下文章