What is the difference between using DatabaseConfig and Database in Slick?

I read about DatabaseConfig in the slick documentation :

In addition to the configuration syntax for Database , there is another layer in the form of DatabaseConfig that allows you to configure the Slick Driver plus a Database match. This simplifies the abstract across various types of database systems by simply modifying the configuration file .

I am not getting this part, how does DatabaseConfig make the underlying database system more abstract than the Database approach? Suppose I use DatabaseConfig in the following test:

 import org.scalatest.{Matchers, FlatSpec} import slick.backend.DatabaseConfig import slick.driver.JdbcProfile import slick.driver.PostgresDriver.api._ import scala.concurrent.ExecutionContext.Implicits.global class DatabaseConfigTest extends FlatSpec with Matchers { def withDb(test: DatabaseConfig[JdbcProfile] => Any) = { val dbConfig = DatabaseConfig.forConfig[JdbcProfile]("abstract") try test(dbConfig) finally dbConfig.db.close() } "DatabaseConfig" should "work" in withDb { dbConfig => import Supplier._ val cities = suppliers.map(_.city) dbConfig.db.run(cities.result).map(_.foreach(println)) } } 

As you can see, if I changed the underlying database system from PostgreSQL to MySQL , in addition to changing the configuration, I need to change the import statement, which imports the postgre API into mysql. On the other hand, if I used Database :

 import org.scalatest.{FlatSpec, Matchers} import slick.driver.PostgresDriver.api._ import slick.jdbc.JdbcBackend.Database import scala.concurrent.ExecutionContext.Implicits.global class DatabaseTest extends FlatSpec with Matchers { def withDb(test: Database => Any) = { val db = Database.forConfig("default") try test(db) finally db.close() } "Supplier names" should "be fetched" in withDb { db => import Supplier._ val names = suppliers.map(_.name) db.run(names.result).map(_.foreach(println)) } } 

When I use Database , the same change in the base database will result in two changes: one in the configuration file, and the other in the source code. With all of this in mind, how is one approach more abstract than another? Am I using DatabaseConfig incorrectly?

+6
source share
1 answer

You are close, but you are not quite using DatabaseConfig correctly. Instead of importing a specific driver, you need to import the driver associated with the configuration. Something like this should work:

 import org.scalatest.{Matchers, FlatSpec} import slick.backend.DatabaseConfig import slick.jdbc.JdbcProfile //import slick.driver.PostgresDriver.api._ import scala.concurrent.ExecutionContext.Implicits.global class DatabaseConfigTest extends FlatSpec with Matchers { def withDb(test: DatabaseConfig[JdbcProfile] => Any) = { val dbConfig = DatabaseConfig.forConfig[JdbcProfile]("abstract") /* The api for the driver specified in the config is imported here. */ import dbConfig.driver.api._ try test(dbConfig) finally dbConfig.db.close() } "DatabaseConfig" should "work" in withDb { dbConfig => import Supplier._ val cities = suppliers.map(_.city) dbConfig.db.run(cities.result).map(_.foreach(println)) } } 

This should allow you to switch databases to a config without having to change code or recompile.

+4
source

All Articles