【问题标题】:Scala-Slick: only part of sequence of actions executedScala-Slick:仅执行部分操作序列
【发布时间】:2017-02-03 04:12:52
【问题描述】:

有一段代码可以添加/更新产品并将一个或多个标签关联到它。标签实际上是添加到与产品相关联的标签组中。

我面临的问题是只有 addOrUpdateProductWithTags() 的“部分”执行。产品已更新或创建,但未添加标签。如果我评论最后一个查询(见评论),那么一切正常。已打开“”以确认这一点。

lazy val pRetId = prods returning prods.map(_.id)

def addTags(keywords: Seq[String]) = {
  for {
    k <- keywords
  } yield {
    tags.filter(_.keyword === k).take(1).result.headOption.flatMap {
      case Some(tag) => { 
        Logger.debug("Using existing tag: " + k)  
        DBIO.successful(tag.id)
      }
      case None => {
        Logger.debug("Adding new tag: " + k)
        tags.returning(tags.map(_.id)) += Tag(k, Some("DUMMY")) 
      }
    } 
  }   
}

def addOrUpdateProductWithTags(prod: Product, tagSet: Seq[String]): Future[Option[Long]] = {

  // handle add or update product
  val prodObject = prod.id match {
    case 0L => pRetId += prod
    case _ => prods.withFilter(_.id === prod.id).update(prod)
  }

  val action = for {
    pid <- prodObject
    tids <- DBIO.sequence(addTags(tagSet))
  } yield (tids, pid)

  val finalAction = action.flatMap {
    case (tids, pid) => {
      val prodId = if (prod.id > 0L) prod.id else pid.asInstanceOf[Number].longValue
      val delAction = tagGroups.filter(_.prodId === prodId).delete
      val tgAction = for {
        tid <- tids
      } yield {
        tagGroups += TagGroup("Ignored-XX", prodId, tid)
      }
      delAction.flatMap { x => DBIO.sequence(tgAction) }

      // IF LINE BELOW IS COMMENTED THEN TagGroup is created else even delete above doesn't happen
      prods.filter(_.id === prodId).map(_.id).result.headOption
    }
  }

  db.run(finalAction.transactionally)
}

这是调用此方法的控制器中的 sn-p。我怀疑来电者等待的时间不够长,但不确定......

val prod = Prod(...)
val tagSet = generateTags(prod.tags)
val add = prodsService.addOrUpdateProductWithTags(prod, tagSet)
add.map { value =>
  Redirect(controllers.www.routes.Dashboard.dashboard)
}.recover {
  case th => 
    InternalServerError("bad things happen in life: " + th)
}         

任何线索有什么问题与查询? 堆栈:Scala 2.11.7,play 版本 2.5.4,play-slick 2.0.0(slick 3.1)

【问题讨论】:

  • 您是否尝试过打印执行的 sql 查询? &lt;logger name="slick.jdbc.JdbcBackend.statement" level="DEBUG" /&gt;
  • 是的,如果最后一行存在,它不会显示删除和后续操作。
  • 可以显示addTags的内容吗?
  • 已编辑 - 还应该补充一点,这段代码在某个时候可以为我工作,突然间我看到了这种行为。不确定是什么原因造成的

标签: mysql scala playframework slick


【解决方案1】:

终于找到解决办法了:

代替以下两行:

    delAction.flatMap { x => DBIO.sequence(tgAction) }
    prods.filter(_.id === prodId).map(_.id).result.headOption

我将操作与 andThen 运算符组合如下:

    delAction >> DBIO.sequence(tgAction) >> prods.filter(_.id === prodId).map(_.id).result.headOption

现在整个序列都被执行了。我仍然不知道原来的解决方案有什么问题,但这可行。

【讨论】:

  • 你要执行的sql查询应该是finalAction的flatMap的最后一行,即action.flatMap{}
  • 最后一行将作为 finalAction 返回
猜你喜欢
  • 2023-03-19
  • 2018-05-10
  • 1970-01-01
  • 2017-09-18
  • 2018-12-10
  • 1970-01-01
  • 2016-11-21
  • 2013-06-19
  • 2017-12-22
相关资源
最近更新 更多