Slick doesn't run Evolutions with Play Framework

101 Views Asked by At

I have an app that was using scala.play with a jdbc connection to a postgresql database and play evolutions and I have been trying to migrate to using slick, to reduce the amount of boilerplate in the database client..

Following the docs for slick does not yeild results which is dissapointing.

here is what i have and what i get, part of build.sbt

libraryDependencies += "com.typesafe.slick" %% "slick" % "3.4.1"
libraryDependencies +="org.slf4j" % "slf4j-nop" % "1.7.26"
libraryDependencies += "com.typesafe.slick" %% "slick-hikaricp" % "3.4.1"
libraryDependencies += "org.postgresql" % "postgresql" % "42.6.0"

// Better field mappings for Postgres/Slick
libraryDependencies += "com.github.tminglei" %% "slick-pg" % "0.21.1"
libraryDependencies += "com.github.tminglei" %% "slick-pg_circe-json" % "0.21.1"

libraryDependencies += "com.typesafe.play" %% "play-slick" % "5.1.0"
libraryDependencies += "com.typesafe.play" %% "play-slick-evolutions" % "5.1.0"

application.conf

slick.dbs.app.profile="slick.jdbc.PostgresProfile$"
slick.dbs.app.db.url = "jdbc:postgresql://localhost:5432/app"
slick.dbs.app.db.user="app"
slick.dbs.app.db.password="password"

and a class

package com.cask.db

import com.google.inject.Inject
import org.joda.time.DateTime
import slick.jdbc.PostgresProfile.api._
import java.sql.Timestamp
import scala.util.Random

class SlickDBClient @Inject()() extends UsersTable {
  val db = Database.forConfig("slick.dbs.app")

  def testAdd(): Unit ={
    val foo = UserTableRow(None,randomString,randomString,true,"2342","234234","234234",None,Some(12),new Timestamp(DateTime.now().getMillis()),new Timestamp(DateTime.now().getMillis()),None,"",None)
    db.run(addUsersQuery.insertOrUpdate(foo))
  }

  def randomString():String = {
    Iterator.continually(Random.nextPrintableChar()).filter(_.isLetterOrDigit).take(8).mkString
  }

  private lazy val addUsersQuery = users returning users.map(_.id) into (
    (f, id) => f.copy(id = Some(id))
  )
}

the cold compiles and runs but evolutions are not applied and testadd can be called without exception , but obviouslyt it isnt working as the evolutions are not being applied,, evolutions were being applied previously without slick just using play and jdbc

I have pushed it to github encase that helps https://github.com/ArthurGibbs/scalaApp

incase anyone looks at the code DatabaseClient was the one i was previously using, using jdbc without slick,, i have set the default for di to use the mock one as i have has to remove some dependances that i have read i could not use at the same time as slick, SlickDBClient is called by an endpoint /api/users/testSlick

please help me understand where i am going wrong

EDIT, updated after some suggestions

[CreationException: Unable to create injector, see the following errors:

1) [Guice/ErrorInCustomProvider]: RuntimeException: Failed to get driver instance for jdbcUrl=jdbc:postgresql://localhost:5432/app
  while locating ApplicationEvolutionsProvider
  at EvolutionsModule.<init>(EvolutionsModule.scala:23):
Binding(class ApplicationEvolutions to ProviderConstructionTarget(class ApplicationEvolutionsProvider) eagerly)
      \_ installed by: Modules$OverrideModule -> GuiceableModuleConversions$$anon$4
  while locating ApplicationEvolutions

Postgresql is version 14.5

1

There are 1 best solutions below

0
Gastón Schabas On

first issue is that play-slick-evolutions is scoped for test in build.sbt. % Test must be removed from

libraryDependencies += "com.typesafe.play" %% "play-slick-evolutions" % "5.1.0" % Test

the second problem is that you are using the play jdbc datsources config instead of slick datasources config in application.conf. Adding the following lines will make the evolutions module work

slick.dbs.app.profile="slick.jdbc.PostgresProfile$"
slick.dbs.app.db.url = "jdbc:postgresql://localhost:5432/app"
slick.dbs.app.db.user="app"
slick.dbs.app.db.password="password"

The article Play Slick Migration Guide - Database configuration helps to understand why your app is not running the evolution scripts

With the past releases of Play Slick (which used Slick 2.1 or earlier), you used to configure Slick datasources exactly like you would configure Play JDBC datasources. This is no longer the case, and the following configuration will now be ignored by Play Slick:

db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.user=sa
db.default.password=""

Here is how you would need to migrate the above configuration:

slick.dbs.default.profile="slick.jdbc.H2Profile$" # You must provide the > required Slick profile! 
slick.dbs.default.db.driver=org.h2.Driver
slick.dbs.default.db.url="jdbc:h2:mem:play"
slick.dbs.default.db.user=sa
slick.dbs.default.db.password=""