【问题标题】:groupBy method throws an error in SlickgroupBy 方法在 Slick 中引发错误
【发布时间】:2014-12-15 04:16:52
【问题描述】:

代码如下所示:

case class Supplier(snum: String, sname: String, status: Int, city: String)

class Suppliers(tag: Tag) extends Table[Supplier](tag, "suppliers") {
  def snum  = column[String]("snum")
  def sname = column[String]("sname")
  def status   = column[Int]("status")
  def city     = column[String]("city")
  def * = (snum, sname, status, city) <> (Supplier.tupled, Supplier.unapply _)
}

val suppliers = TableQuery[Suppliers]

val gr=suppliers.groupBy(_.city).map{ case (k,v) => (k, v) }.buildColl[Set]

当我编译它时,它会抱怨:

Error:(69, 43) No matching Shape found.
Slick does not know how to map the given types.
Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List).
  Required level: scala.slick.lifted.FlatShapeLevel
     Source type: (scala.slick.lifted.Column[String], scala.slick.lifted.Query[A$A113.this.Suppliers,A$A113.this.Supplier,[+A]Seq[A]])
   Unpacked type: T
     Packed type: G
lazy val gr=suppliers.groupBy(_.city).map{ case (k,v) => (k, v) }.buildColl[Set]
                      ^
Error:(69, 43) not enough arguments for method map: (implicit shape: scala.slick.lifted.Shape[_ <: scala.slick.lifted.FlatShapeLevel, (scala.slick.lifted.Column[String], scala.slick.lifted.Query[A$A113.this.Suppliers,A$A113.this.Suppliers#TableElementType,Seq]), T, G])scala.slick.lifted.Query[G,T,Seq].
Unspecified value parameter shape.
lazy val gr=suppliers.groupBy(_.city).map{ case (k,v) => (k, v) }.buildColl[Set]
                      ^

但如果我将case(k,v)=&gt;(k,v) 更改为case(k,v)=&gt;(k,v.length),它会再次起作用。

有人对此有想法吗?

【问题讨论】:

  • 你想在这个声明中做什么 - map{ case (k,v) =&gt; (k, v) }。我认为您可以通过 map 得到任何东西。

标签: scala playframework playframework-2.0 slick slick-2.0


【解决方案1】:

原因是:Scala 的 groupBy 返回一个Map[..., Seq[...]],换句话说,一个包含其他集合的集合。嵌套集合!但是 SQL 不支持嵌套集合,它总是返回平面表。支持嵌套集合需要比 Slick 目前更复杂的从 Scala 到 SQL 的转换。所以相反,Slick 禁止这种情况,并要求你把它弄平。例如,case(k,v)=&gt;(k,v.length) 就是这样做的,它将类型转换为 Map[..., Int]。 Slick 通过说 Required level: scala.slick.lifted.FlatShapeLevel 告诉你。

一种解决方法是在客户端上进行分组,例如suppliers.run.groupBy(_.city) 或在 Slick 2.2 及更高版本中 db.run(suppliers).groupBy(_.city). 在连接的情况下,运行两个查询并在本地连接它们会更有效,而不是传输笛卡尔积并在之后进行分组。

【讨论】:

    猜你喜欢
    • 2017-03-03
    • 2020-04-08
    • 2012-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    相关资源
    最近更新 更多