masgo masgo - 2 months ago 27
Scala Question

Scala+Slick 3: Inserting the result of one query into another table

This question is about slick 3.0 or 3.1 (I am flexible about that)

I have an intermediate query which I process with

map
,
for
, etc. to obtain the result I want. In the end I have a

val foo: DBIOAction[Seq[MySchema.Bar], NoStream, Effect.Read]


Now I have a
val bar: TableQuery[MySchema.Bar]
and I want to insert foo in to it.

If foo would be a
Seq
I could simply do
bar ++= foo
, but it is not.

The only way I found is to materialize the result by awaiting it. Like this

val query = (bar ++= Await.result(db.run(foo), Duration.Inf))


Obviously
query
needs to be run at some point with
db.run
. But now I have two DB-runs. Wouldn't it be better to have everything in a single run?

Is there a better way to do this?

Answer

DBIOAction has map/flatMap functions, so you can write something like

val insertAction = foo.flatMap(bar ++= _)

The insertAction will be of type DBIOAction[Int, NoStream, Effect.Write] or something like that (I'm not entirely sure about Int and the effect), then you can run it on the DB as any DBIOAction using db.run; what you then get is a future of the overall query and insert result.