首页 > 解决方案 > 如何在 Slick 中将“FixedSqlAction”转换为“StreamingDBIO”?

问题描述

我正在使用 Alpakka 和 Slick 模块创建一个 akka-stream,但我遇到了类型不匹配的问题。

一个分支是关于在他们的表中获取发票总数:

  def getTotal(implicit session: SlickSession) = {
    import session.profile.api._
    val query = TableQuery[Tables.Invoice].length.result
    Slick.source(query)
  }

但是最后一行没有编译,因为 Alpakka 期待 aStreamingDBIO但我提供了FixedSqlAction[Int,slick.dbio.NoStream,slick.dbio.Effect.Read].

如何从非流媒体结果转移到流媒体结果?

标签: slickakka-streamslick-3.0alpakka

解决方案


获取表的长度会产生单个值,而不是流。所以最简单的获取Source流的方法是

def getTotal(implicit session: SlickSession): Source[Int, NotUsed] =
  Source.lazyFuture { () =>
    // Don't actually run the query until the stream has materialized and
    //  demand has reached the source
    val query = TableQuery[Tables.Invoice].length.result
    session.db.run(query)
  }

Alpakka 的 Slick 连接器更面向具有大量结果的查询的流式处理(包括管理分页等)结果。对于单个结果,将Futurevanilla Slick 为您提供的结果转换为流就足够了。

如果您想在调用后立即开始执行查询getTotal(请注意,无论下游是否曾经运行或需要来自源的数据),您可以

def getTotal(implicit session: SlickSession): Source[Int, NotUsed] = {
  val query = TableQuery[Tables.Invoice].length.result
  Source.future(session.db.run(query))
}

推荐阅读