“找不到存储在数据集中的类型的编码器”和“方法映射的参数不足”?

Posted

技术标签:

【中文标题】“找不到存储在数据集中的类型的编码器”和“方法映射的参数不足”?【英文标题】:"Unable to find encoder for type stored in a Dataset" and "not enough arguments for method map"? 【发布时间】:2017-07-17 16:46:51 【问题描述】:

以下代码在最后一个map(...) 上出现了两个错误。 map() 函数中缺少什么参数?如何解决“编码器”的错误?

错误:

错误:(60, 11) 无法找到存储在数据集中的类型的编码器。通过导入 spark.implicits 支持原始类型(Int、String 等)和产品类型(案例类)。未来版本中将添加对序列化其他类型的支持。 .map(r => Cols(r.getInt(0), r.getString(1), r.getString(2), r.getString(3), r.getDouble(4), r.getDate(5), r.getString(6), r.getString(7), r.getDouble(8), r.getString(9))) 错误:(60, 11) 方法映射的参数不足:(隐式证据 $6: org.apache.spark.sql.Encoder[Cols])org.apache.spark.sql.Dataset[Cols]。 未指定值参数证据$6。 .map(r => Cols(r.getInt(0), r.getString(1), r.getString(2), r.getString(3), r.getDouble(4), r.getDate(5), r.getString(6), r.getString(7), r.getDouble(8), r.getString(9)))

代码:

  case class Cols (A: Int,
                   B: String,
                   C: String,
                   D: String,
                   E: Double,
                   F: Date,
                   G: String,
                   H: String,
                   I: Double,
                   J: String
                  )

class SqlData(sqlContext: org.apache.spark.sql.SQLContext, jdbcSqlConn: String) 
  def getAll(source: String) = 
    sqlContext.read.format("jdbc").options(Map(
      "driver" -> "com.microsoft.sqlserver.jdbc.SQLServerDriver",
      "url" -> jdbcSqlConn,
      "dbtable" -> s"MyFunction('$source')"
    )).load()
      .select("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")
      // The following line(60) got the errors.
      .map((r) => Cols(r.getInt(0), r.getString(1), r.getString(2), r.getString(3), r.getDouble(4), r.getDate(5), r.getString(6), r.getString(7), r.getDouble(8), r.getString(9)))
  


更新:

我有以下功能

def compare(sqlContext: org.apache.spark.sql.SQLContext, dbo: Dataset[Cols], ods: Dataset[Cols]) = 
    import sqlContext.implicits._
    dbo.map((r) => ods.map((s) =>  // Errors occur here
      0
    ))

它得到了同样的错误。

    为什么我导入sqlContext.implicits._后还是报错? 我创建了一个新参数sqlContext 只是为了导入。有没有更好的方法?

【问题讨论】:

为什么不select.as[Cols] 您是否按照错误提示import spark.implicits._?而且,缺少的参数是隐式编码器,所以它是同一个问题,解决一个,你已经解决了另一个。 @TzachZohar 当我将import org.apache.spark.implicits._ 放在顶部时出现cannot resolve symbol implicits. 的错误? @T.Gawęda as[Cols].as[Cols] 上遇到了同样的错误。 你应该有一个 SparkSession 的实例,它通常命名为spark,这就是你导入的内容。您还可以通过 SQLContext 实例使用 import sqlContext.implicits._ 【参考方案1】:

将所有的 cmets 组合成一个答案:

def getAll(source: String): Dataset[Cols] = 
  import sqlContext.implicits._ // this imports the necessary implicit Encoders

  sqlContext.read.format("jdbc").options(Map(
    "driver" -> "com.microsoft.sqlserver.jdbc.SQLServerDriver",
    "url" -> jdbcSqlConn,
    "dbtable" -> s"MyFunction('$source')"
  )).load().as[Cols] // shorter way to convert into Cols, thanks @T.Gaweda

【讨论】:

我刚刚更新了底部的问题。即使我导入了隐式函数,函数仍然会出错? 我在这里创建了一个新问题***.com/questions/45150713/…。

以上是关于“找不到存储在数据集中的类型的编码器”和“方法映射的参数不足”?的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis学习第22节 -- 高级结果映射 构造方法映射

以代码优先方法映射 SQL 视图

处理不明确的处理程序方法映射约定

jQuery 到常规 Javascript 的映射

使用表单主体的 Spring MVC Controller 方法映射

stream流的map方法,映射方法,将一种类型转成另一个类型,使用的是function接口,比如把Integer转成String