使用连接查询后 Scala 光滑更新 table
Scala slick update table after querying with a join
我想更新 table 但需要根据特定条件选择该行。以下代码编译正常但抛出 运行 次异常:
play.api.http.HttpErrorHandlerExceptions$$anon: Execution exception[[SlickException: A query for an UPDATE statement must resolve to a comprehension with a single table -- Unsupported shape: Comprehension s2, Some(Apply Function =), None, ConstArray(), None, None, None, None]]
函数如下(目的是只允许合格用户更新):
def updateRecord(record: Record)(implicit loggedInUserId: User) = {
val q = records.withFilter(_.id === record.id).join(companies).on(_.companyId === _.id).filter(_._2.userid === loggedInUserId)
val recordToUpdate = q.map { case (r, c) => r }
val action = for {
c <- recordToUpdate.update(record)
} yield (c)
... // there are other actions in the for comprehension, removed them for clarity
我认为地图的结果是记录 table 中的一行(不是元组),但错误似乎表明我没有更新 "single" table.
或者有更好的查询+更新方式吗?
是的,您似乎尝试更新两个表。
也许你应该试试
def updateRecord(record: Record)(implicit loggedInUserId: User): Future[Int] = {
val recordToUpdate = records.filter(_.id === record.id)
val q = recordToUpdate
.join(companies).on(_.companyId === _.id)
.filter(_._2.userid === loggedInUserId)
.exists
val action = for {
c <- recordToUpdate.update(record)
// ...
} yield c
for {
isLoggedIn <- db.run(q.result)
if isLoggedIn
c <- db.run(action)
} yield c
}
你也可以试试
def updateRecord(record: Record)(implicit loggedInUserId: User):
DBIOAction[Int, NoStream, Read with Write with Transactional] = {
val recordToUpdate = records.filter(_.id === record.id)
val action =
recordToUpdate
.join(companies).on(_.companyId === _.id)
.filter(_._2.userid === loggedInUserId)
.exists
.result
(for {
isLoggedIn <- action
if isLoggedIn
c <- recordToUpdate.update(record)
// ...
} yield c).transactionally
}
无需 NoSuchElementException: Action.withFilter failed
即可工作的变体。基于 .
def updateRecord(record: Record)(implicit loggedInUserId: User):
DBIOAction[Int, NoStream, Read with Write with Transactional] = {
val recordToUpdate = records.filter(_.id === record.id)
val action =
recordToUpdate
.join(companies).on(_.companyId === _.id)
.filter(_._2.userid === loggedInUserId)
.exists
.result
action.flatMap {
case true => for {
c <- recordToUpdate.update(record)
// ...
} yield c
case false => DBIO.successful(0) /*DBIO.failed(new IllegalStateException)*/
}.transactionally
}
我想更新 table 但需要根据特定条件选择该行。以下代码编译正常但抛出 运行 次异常:
play.api.http.HttpErrorHandlerExceptions$$anon: Execution exception[[SlickException: A query for an UPDATE statement must resolve to a comprehension with a single table -- Unsupported shape: Comprehension s2, Some(Apply Function =), None, ConstArray(), None, None, None, None]]
函数如下(目的是只允许合格用户更新):
def updateRecord(record: Record)(implicit loggedInUserId: User) = {
val q = records.withFilter(_.id === record.id).join(companies).on(_.companyId === _.id).filter(_._2.userid === loggedInUserId)
val recordToUpdate = q.map { case (r, c) => r }
val action = for {
c <- recordToUpdate.update(record)
} yield (c)
... // there are other actions in the for comprehension, removed them for clarity
我认为地图的结果是记录 table 中的一行(不是元组),但错误似乎表明我没有更新 "single" table.
或者有更好的查询+更新方式吗?
是的,您似乎尝试更新两个表。
也许你应该试试
def updateRecord(record: Record)(implicit loggedInUserId: User): Future[Int] = {
val recordToUpdate = records.filter(_.id === record.id)
val q = recordToUpdate
.join(companies).on(_.companyId === _.id)
.filter(_._2.userid === loggedInUserId)
.exists
val action = for {
c <- recordToUpdate.update(record)
// ...
} yield c
for {
isLoggedIn <- db.run(q.result)
if isLoggedIn
c <- db.run(action)
} yield c
}
你也可以试试
def updateRecord(record: Record)(implicit loggedInUserId: User):
DBIOAction[Int, NoStream, Read with Write with Transactional] = {
val recordToUpdate = records.filter(_.id === record.id)
val action =
recordToUpdate
.join(companies).on(_.companyId === _.id)
.filter(_._2.userid === loggedInUserId)
.exists
.result
(for {
isLoggedIn <- action
if isLoggedIn
c <- recordToUpdate.update(record)
// ...
} yield c).transactionally
}
无需 NoSuchElementException: Action.withFilter failed
即可工作的变体。基于
def updateRecord(record: Record)(implicit loggedInUserId: User):
DBIOAction[Int, NoStream, Read with Write with Transactional] = {
val recordToUpdate = records.filter(_.id === record.id)
val action =
recordToUpdate
.join(companies).on(_.companyId === _.id)
.filter(_._2.userid === loggedInUserId)
.exists
.result
action.flatMap {
case true => for {
c <- recordToUpdate.update(record)
// ...
} yield c
case false => DBIO.successful(0) /*DBIO.failed(new IllegalStateException)*/
}.transactionally
}