Spark隐式转换的参数多态问题:Seq[T]无toDF成员
问题原因
Spark的toDF()方法将Seq转为DataFrame时,必须依赖**隐式的Encoder[T]**完成对象到Spark内部数据格式的转换。你的泛型方法仅声明了T <: schemas.QuestionSchema,但未要求该隐式Encoder存在,编译器无法自动推导并生成对应T的Encoder,因此报错“value toDF is not a member of Seq[T]”。
解决办法
有两种简洁的修复方式:
方式一:为泛型方法添加隐式Encoder参数
修改方法签名,显式要求Encoder[T]作为隐式参数,Spark会通过spark.implicits._自动为case class生成对应的Encoder:
import org.apache.spark.sql.{DataFrame, Encoder, SparkSession} import schemas.QuestionSchema trait DataStore { var data1 = Array.empty[Data1Type] var data2 = Array.empty[Data2Type] def convertToDf[T <: QuestionSchema](res: Array[T])(implicit spark: SparkSession, enc: Encoder[T]): DataFrame = { import spark.implicits._ res.toSeq.toDF() } }
方式二:使用SparkSession.createDataFrame结合ClassTag
利用ClassTag保留泛型类型的运行时信息,直接调用createDataFrame构造DataFrame:
import org.apache.spark.sql.{DataFrame, SparkSession} import schemas.QuestionSchema import scala.reflect.ClassTag trait DataStore { var data1 = Array.empty[Data1Type] var data2 = Array.empty[Data2Type] def convertToDf[T <: QuestionSchema : ClassTag](res: Array[T])(implicit spark: SparkSession): DataFrame = { spark.createDataFrame(res) } }
内容的提问来源于stack exchange,提问作者Ken Myers
相关产品推荐
相关产品推荐

