0

I'm creating an akka-stream using Alpakka and the Slick module but I'm stuck in a type mismatch problem.

One branch is about getting the total number of invoices in their table:

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

But the end line doesn't compile because Alpakka is expecting a StreamingDBIO but I'm providing a FixedSqlAction[Int,slick.dbio.NoStream,slick.dbio.Effect.Read].

How can I move from the non-streaming result to the streaming one?

tonicebrian
  • 4,715
  • 5
  • 41
  • 65

2 Answers2

2

Taking the length of a table results in a single value, not a stream. So the simplest way to get a Source to feed a stream is

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's Slick connector is more oriented towards streaming (including managing pagination etc.) results of queries that have a lot of results. For a single result, converting the Future of the result that vanilla Slick gives you into a stream is sufficient.

If you want to start executing the query as soon as you call getTotal (note that this whether or not the downstream ever runs or demands data from the source), you can have

def getTotal(implicit session: SlickSession): Source[Int, NotUsed] = {
  val query = TableQuery[Tables.Invoice].length.result
  Source.future(session.db.run(query))
}
Levi Ramsey
  • 18,884
  • 1
  • 16
  • 30
0

Would sth like this work for you?

def getTotal() = {
  // Doc Expressions (Scalar values)
  // https://scala-slick.org/doc/3.2.0/queries.html
  val query = TableQuery[Tables.Invoice].length.result

  val res = Await.result(session.db.run(query), 60.seconds)
  println(s"Result: $res")
  res
}
earthling paul
  • 503
  • 4
  • 8