I've been running Slick against our Oracle database for a while. Now I'd like to also use it against H2, in our integration tests. I imagined this to be only about changing the drivers being loaded, but now I realized all my repositories are riddled with a import slick.jdbc.OracleProfile.api._
, which makes me think my repositories are at this moment tied to OracleSQL.
What would the standard procedure be to have Slick support loading either Oracle or H2 drivers based on different configuration files?
You'll need to abstract the Slick profile via JdbcProfile
. That will get rid of the Oracle-specific parts you've identified as the problem.
It sounds like you have a reasonably large application. In that case, it's common (in my experience) to make the Slick profile a parameter to a class or trait, and then pass in the specific profile when you know what it is.
For example (using the sample code in Essential Slick) we can say that our application profile must have a JdbcProfile
:
import slick.jdbc.JdbcProfile
trait Profile {
val profile: JdbcProfile
}
Then, for each module of the database code, we import the profile API:
trait DatabaseModule1 { self: Profile =>
import profile.api._
// Write database code here
}
Notice how the abstract profile.api._
import replaces a database specific slick.jdbc.OracleProfile.api._
If you have many modules you can combine them all together into a case class:
class DatabaseLayer(val profile: JdbcProfile) extends
Profile with
DatabaseModule1 with
DatabaseModule2
And finally, at the edge of your program you can decide what configuration to use:
object Main extends App {
// At this point, you can make a test and decide which specific
// database you want to use. Here I'm saying it's always H2:
val databaseLayer = new DatabaseLayer(slick.jdbc.H2Profile)
// You can now use methods in `databaseLayer`,
// or pass it to other modules in your system
}
This is described further in:
DbConfig and Multi DB patterns in the Slick Manual, which also describes useful tricks for selecting different configurations that you've defined inside application.conf
.