Scala Spark toDF在导入sqlContext隐式后无法解析符号
我正在为Scala Spark应用程序编写一些单元测试 为此,我需要在测试中创建不同的数据帧。因此,我编写了一个非常简短的DFsBuilder代码,它基本上允许我添加新行并最终创建DF。代码是:Scala Spark toDF在导入sqlContext隐式后无法解析符号,scala,apache-spark,dataframe,apache-spark-sql,Scala,Apache Spark,Dataframe,Apache Spark Sql,我正在为Scala Spark应用程序编写一些单元测试 为此,我需要在测试中创建不同的数据帧。因此,我编写了一个非常简短的DFsBuilder代码,它基本上允许我添加新行并最终创建DF。代码是: class DFsBuilder[T](private val sqlContext: SQLContext, private val columnNames: Array[String]) { var rows = new ListBuffer[T]() def add(row: T): D
class DFsBuilder[T](private val sqlContext: SQLContext, private val columnNames: Array[String]) {
var rows = new ListBuffer[T]()
def add(row: T): DFsBuilder[T] = {
rows += row
this
}
def build() : DataFrame = {
import sqlContext.implicits._
rows.toList.toDF(columnNames:_*) // UPDATE: added :_* because it was accidently removed in the original question
}
}
但是,toDF方法不会使用无法解析符号toDF进行编译
我用泛型编写了这个构建器代码,因为我需要创建不同类型的DFs(不同的列数和不同的列类型)。我希望使用它的方式是在单元测试中定义一些特定的case类,并将其用于构建器
我知道这个问题在某种程度上与我使用泛型(可能是某种类型的类型擦除问题)这一事实有关,但我不太清楚到底是什么问题
所以我的问题是:
- 有人能告诉我问题出在哪里吗?还有希望如何修复它
- 如果这个问题不能用这种方法解决,有人能提供另一种优雅的方法来创建数据帧吗?(我不喜欢用创建代码污染我的单元测试)
提前感谢如果您查看
toDF
和SQLImplicits.localSeqToDataFrameHolder
(使用的隐式函数)的签名,您将能够检测到两个问题:
T
必须是Product
的子类(所有大小写类的超类,元组…),并且必须为其提供隐式TypeTag
。要解决此问题,请将类的声明更改为:
class DFsBuilder[T <: Product : TypeTag](...) { ... }
通过这两个更改,您的代码可以编译(并工作) 实际上,第二个项目中使用了列名,我可能不小心擦掉了它或其他什么。我为此道歉。扩展产品和类型标签确实有效!非常感谢:)只是添加了应该使用导入scala.reflect.runtime.universe.TypeTag导入TypeTag的用法:
import-scala.reflect.runtime.universe.TypeTag
,因为Java显然也有一个TypeTag类
rows.toList.toDF(columnNames: _*)