Advice for using single database session with Database.run / Slick 3?

400 views
Skip to first unread message

Tim Harper

unread,
Jul 22, 2015, 4:55:39 AM7/22/15
to Slick / ScalaQuery
In our functional tests, we wrap each test in a transaction and ROLLBACK at the end in order to keep our test database clean. With Slick 3, what is the best way to achieve this? I saw that actionContext has a `pin` method, which looks like maybe something I want.

Can somebody point me to a resource? I'm having a hard time finding an answer for this one.

Thank you!

Tim

Rich Hanbidge

unread,
Aug 7, 2015, 7:46:26 PM8/7/15
to Slick / ScalaQuery
+1, we're doing the same thing, and I can't figure out a way to get this to work.

Stefan Zeiger

unread,
Aug 10, 2015, 7:31:24 AM8/10/15
to scala...@googlegroups.com
On 2015-08-08 1:46, Rich Hanbidge wrote:
+1, we're doing the same thing, and I can't figure out a way to get this to work.

On Wednesday, July 22, 2015 at 1:55:39 AM UTC-7, Tim Harper wrote:
In our functional tests, we wrap each test in a transaction and ROLLBACK at the end in order to keep our test database clean. With Slick 3, what is the best way to achieve this? I saw that actionContext has a `pin` method, which looks like maybe something I want.

If you really want to run it on an existing Session: https://github.com/slick/slick/blob/3.0.1/slick-testkit/src/main/scala/com/typesafe/slick/testkit/util/TestDB.scala#L185-L193

If all you need is a rollback, something like this should do the trick:

case class AbortTx(r: Any) extends Exception

def wrap[T](a: DBIO[T]): DBIO[T] = a.map[T](r => throw new AbortTx(r)).transactionally.asTry.map[T] {
  case Failure(AbortTx(r)) => r.asInstanceOf[T]
  case Failure(t) => throw t
}

If you need it to work for streaming, you'll have to drop down by one level and start with https://github.com/slick/slick/blob/3.0.1/slick/src/main/scala/slick/driver/JdbcActionComponent.scala#L87-L89. The StartTransaction/Commit/Rollback actions are not accessible in JdbcActionComponent but you can copy & paste them.

--
Stefan Zeiger
Slick Tech Lead
Typesafe - Build Reactive Apps!
Twitter: @StefanZeiger

Rich Hanbidge

unread,
Aug 10, 2015, 12:40:14 PM8/10/15
to Slick / ScalaQuery
Thanks Stefan - These examples should get me started. 
Cheers!
Rich

Rich Hanbidge

unread,
Aug 10, 2015, 1:16:16 PM8/10/15
to Slick / ScalaQuery
I see how I can use your suggestions, but I'd like to understand what the idiomatic "slick" way is to test low level DB connectivity.  I'll rephrase my question, and would love any suggestions you have.  I've found that sometimes asking for a solution (i.e. session rollback) gets in the way of the right way to solve the problem (see below).

Test Requirement - I'd like to ensure that my slick queries work with my PostGres DB schema.  Basic Create/Read/Update/Delete stuff for now, but eventually more complex queries.  A test which inserts a record, and verifies that the record can be read, is sufficient for me to extrapolate.  I'd really like to avoid having tests leave records in the database, which is the motivation for this discussion post.

Thanks in advance for any suggestions or pointers you have.  If this isn't a first class scenario for Slick, I can add a feature request.  If you/TypeSafe have a different philisophical perspective on testing at this level, I'd love that too.  :)

Tim Harper

unread,
Aug 21, 2015, 5:15:52 AM8/21/15
to Slick / ScalaQuery
Thanks for the tip, Rich. It was close to what I needed, but ended up being insufficient as I need to share the Session instance itself, otherwise withTransaction calls were putting the connection into autoCommit mode (because they didn't know they were already in a transaction).

Here was my solution:


A bit heavy handed :( but it works.
Reply all
Reply to author
Forward
0 new messages