【问题标题】:No implicits arguments of type T, Trying to cast a dataframe to a Dataset[T]没有 T 类型的隐含参数,尝试将数据帧转换为 Dataset[T]
【发布时间】:2020-05-23 00:53:21
【问题描述】:

我正在尝试构建一个通用函数来整合一些 mongoDb 集合,我正在使用案例类来键入集合,并在我的函数中接收类型作为参数 [T],如下所示:

  def refreshCollection[T](newDS:Dataset[T],oldDS:Dataset[T]): Dataset[T]={
    val filteredOldDS=oldDS.join(newDS, Seq("id"),"left_anti").as[T]
    filteredOldDS.union(newDS)
  }

问题是当我尝试使用 .as[T] 将连接的 Dataframe 结果转换为原始案例类以返回 Dataset[T] 时,我遇到了这个错误,即使我已经导入了 sparkSession.implicits._:

no implicit arguments of type: Encoder[T]

有趣的是,当我使用固定的 case 类进行转换工作正常时,有什么建议吗?

提前致谢!

【问题讨论】:

    标签: scala apache-spark implicit


    【解决方案1】:

    我认为这是因为您的代码不能保证在必要时会有Encoder[T] 可用。

    您可以尝试使用隐式解码器参数化您的参数,并推迟编译器尝试找到所需解码器的时间。

      def refreshCollection[T](newDS:Dataset[T],oldDS:Dataset[T])(implicit enc: Encoder[T]): Dataset[T]={
        val filteredOldDS=oldDS.join(newDS, Seq("id"),"left_anti").as[T]
        filteredOldDS.union(newDS)
      }
    

    当然,在调用refreshCollection 时,您需要以某种方式将Encoder[MyCaseClass] 纳入范围

    【讨论】:

    • 您好,感谢您的回答,我认为您在使用编码器的解码器中打错字了,无论如何我都尝试过这种方法,但现在我得到了No implicits found for parameter enc: Encoder[MyCaseClass]
    • 是的,没错。已更正。您写道,当您为特定案例类进行转换时,它会起作用。那你用import sparkSession.implicits._吗?如果是这样,您需要在调用refreshCollection()时进行相同的导入
    • 如果编写具有特定类型的方法可以正常工作,但是当您将其设为通用并且调用它时它不起作用,这意味着可能有另一个导入将编码器带入范围比import sparkSession.implicits._,你在你定义refreshCollection的地方有,但是你没有把它添加到你调用方法的地方。
    • 非常感谢,我是从另一个类调用函数,所以是的,我也有 tom import sparkSession.implicits._,再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    相关资源
    最近更新 更多