I'm trying to generate the Scala code for the database tables and views in my schema using Slick 3.0.3. Taking this blog as example I have the following file build.sbt
. However, this will generate code for my database tables and will not include the database views. How can I get the views generated as well?
According to slick issue 1022 I see it is possible to do but the API doesn't look alike and slick.codegen.SourceCodeGenerator
doesn't have a getTables
or defaultTables
to include view names.
name := "slickCodeGen"
version := "1.0"
scalaVersion := "2.11.6"
scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8")
libraryDependencies ++= Seq(
"com.typesafe.slick" %% "slick" % "3.0.3",
"com.typesafe.slick" %% "slick-codegen" % "3.0.3",
"org.postgresql" % "postgresql" % "9.4-1201-jdbc41",
"com.zaxxer" % "HikariCP" % "2.3.2",
"org.scalatest" %% "scalatest" % "2.2.4" % "test"
)
slick <<= slickCodeGenTask
sourceGenerators in Compile <+= slickCodeGenTask
lazy val slick = TaskKey[Seq[File]]("gen-tables")
lazy val slickCodeGenTask = (sourceManaged, dependencyClasspath in Compile, runner in Compile, streams) map { (dir, cp, r, s) =>
val outputDir = (dir / "main/slick").getPath
val username = "postgres"
val password = "xxx"
val url = "jdbc:postgresql://localhost:5555/testdb?searchpath=public"
val jdbcDriver = "com.postgresql.jdbc.Driver"
val slickDriver = "slick.driver.PostgresDriver"
val pkg = "folder1.folder2"
toError(r.run("slick.codegen.SourceCodeGenerator", cp.files, Array(slickDriver, jdbcDriver, url, outputDir, pkg, username, password), s.log))
val fname = outputDir + "/folder1/folder2/" + "Tables.scala"
Seq(file(fname))
}
After a lot of trial and error due to the many changes in the Slick generator API the following standalone application Generator.scala
tested will generate the code for both tables and views under Slick 3.0.3:
import java.util.concurrent.TimeUnit
import slick.driver.PostgresDriver
import slick.jdbc.meta.MTable
import slick.codegen.SourceCodeGenerator
import slick.driver.PostgresDriver.simple._
import play.api.libs.concurrent.Execution.Implicits._
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
object Generator extends App {
val slickDriver = "slick.driver.PostgresDriver"
val jdbcDriver = "org.postgresql.Driver"
val url = "jdbc:postgresql://localhost:5555/testdb?searchpath=public"
val outputDir = "/tmp/"
val pkg = "folder1.folder2"
val username = "postgres"
val password = "xxx"
val db = Database.forURL(url, user, password)
val dbio = PostgresDriver.createModel(Some(MTable.getTables(None, None, None, Some(Seq("TABLE", "VIEW")))))
val model = db.run(dbio)
val future : Future[SourceCodeGenerator] = model.map(model => new SourceCodeGenerator(model))
val codegen : SourceCodeGenerator = Await.result(future, Duration.create(5, TimeUnit.MINUTES))
codegen.writeToFile(slickDriver, outputDir, pkg, "Tables", "Tables.scala")
}
Integrating this code into a build.sbt
is not that easy because requires defining an external custom code generator file and then compiling and running it from the build.sbt
before the actual project is compiled. A very outdated example of this can be found in the github project slick-codegen-customization-example but note that they don't have a build.sbt
but a more advanced Build.scala
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With