[英]Executing non-database actions in a transaction in Slick 3
我無法理解新的Slick DBIOAction
API,它似乎在文檔中沒有很多示例。 我正在使用Slick 3.0.0,我需要執行一些數據庫操作以及從數據庫接收的數據的一些計算,但所有這些操作都必須在單個事務中完成。 我正在嘗試執行以下操作:
types
表)。 messages
表 - 由於某些限制,此查詢必須在原始SQL中)。 我希望步驟1和3中的查詢在事務內執行,因為結果集中的數據必須一致。
我試圖用monadic join樣式做到這一點。 這是我的代碼的過度簡化版本,但我甚至無法編譯:
val compositeAction = (for {
rawTypes <- TableQuery[DBType].result
(projectId, types) <- rawTypes.groupBy(_.projectId).toSeq.map(group => (group._1, group._2.slice(0, 10)))
counts <- DBIO.sequence(types.map(aType => sql"""select count(*) from messages where type_id = ${aType.id}""".as[Int]))
} yield (projectId, types.zip(counts))).transactionally
for
理解選擇來自所述數據types
表。 for
理解應該做的結果的一些分組和切片,從而產生Seq[(Option[String], Seq[String])]
for
上一步中的每個元素執行一組查詢,特別是,它必須為Seq[String]
每個值執行單個SQL查詢。 所以在第三行中我構建了一系列DBIOAction
。 yield
子句zip
小號types
從第二步驟和counts
從第三步。 但是,這種結構不起作用,並且會產生兩個編譯時錯誤:
Error:(129, 16) type mismatch;
found : slick.dbio.DBIOAction[(Option[String], Seq[(com.centreit.proto.repiso.storage.db.models.DBType#TableElementType, Vector[Int])]),slick.dbio.NoStream,slick.dbio.Effect]
(which expands to) slick.dbio.DBIOAction[(Option[String], Seq[(com.centreit.proto.repiso.storage.db.models.TypeModel, Vector[Int])]),slick.dbio.NoStream,slick.dbio.Effect]
required: scala.collection.GenTraversableOnce[?]
counts <- DBIO.sequence(types.map(aType => sql"""select count(*) from messages where type_id = ${aType.id}""".as[Int]))
^
Error:(128, 28) type mismatch;
found : Seq[Nothing]
required: slick.dbio.DBIOAction[?,?,?]
(projectId, types) <- rawTypes.groupBy(_.projectId).toSeq.map(group => (group._1, group._2.slice(0, 10)))
^
我試圖通過使用DBIO.successful
來包裝DBIOAction
的第二行,這應該將一個常量值提升到DBIOAction
monad中:
(projectId, types) <- DBIO.successful(rawTypes.groupBy(_.projectId).toSeq.map(group => (group._1, group._2.slice(0, 10))))
但在此代碼中, types
變量被推斷為Any
,並且代碼因此而無法編譯。
試試這種方式:
val compositeAction = (for {
rawTypes <- TableQuery[DBType].result
pair <- DBIO.sequence(rawTypes.groupBy(_.projectId).toSeq.map(group => DBIO.successful(group)))
counts <- DBIO.sequence(pair.head._2.map(aType => sql"""select count(*) from messages where type_id = ${aType.id}""".as[Int]))
} yield (pair.head._1, pair.head._2.zip(counts))).transactionally
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.