如何使用复合键在Slick中过滤和更新表?

时间:2018-01-24 12:45:01

标签: database scala slick

我有一张桌子:

trait Schema {
    val db: Database

    class CoffeeTable(tag: Tag) extends Table[Coffee](tag, "coffees") {
        def from = column[String]("from")
        def kind = column[String]("kind")
        def sold = column[Boolean]("sold")
    }

    protected val coffees = TableQuery[Coffee]
}

我想更新已售出的条目。这是我最终得到的方法:

  def markAsSold(soldCoffees: Seq[Coffee]): Future[Int] = {
    val cmd = coffees
      .filter { coffee =>
        soldCoffees
          .map(sc => coffee.from === sc.from && coffee.kind === sc.kind)
          .reduceLeftOption(_ || _)
          .getOrElse(LiteralColumn(false))
      }
      .map(coffee => coffee.sold)
      .update(true)
    db.db.stream(cmd)
  }

虽然它适用于一个小的soldCoffee集合,但它输入了数百个元素后严重失败:

java.lang.StackOverflowError
    at slick.ast.TypeUtil$$colon$at$.unapply(Type.scala:325)
    at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.expr(JdbcStatementBuilderComponent.scala:311)
    at slick.jdbc.H2Profile$QueryBuilder.expr(H2Profile.scala:99)
    at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8(JdbcStatementBuilderComponent.scala:381)
    at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8$adapted(JdbcStatementBuilderComponent.scala:381)
    at slick.util.SQLBuilder.sep(SQLBuilder.scala:31)
    at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.expr(JdbcStatementBuilderComponent.scala:381)
    at slick.jdbc.H2Profile$QueryBuilder.expr(H2Profile.scala:99)
    at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8(JdbcStatementBuilderComponent.scala:381)
    at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8$adapted(JdbcStatementBuilderComponent.scala:381)
    at slick.util.SQLBuilder.sep(SQLBuilder.scala:31)

所以问题是 - 还有另一种方法可以进行此类更新吗?

我想到的是使用简单的SQL查询或引入一些人工列,其中包含fromtype列的连接值并对其进行过滤。

0 个答案:

没有答案