【问题标题】:How to use Slick code generator to include database views as well?如何使用 Slick 代码生成器来包含数据库视图?
【发布时间】:2015-12-21 18:40:16
【问题描述】:

我正在尝试使用 Slick 3.0.3 为我的架构中的数据库表和视图生成 Scala 代码。以this blog 为例,我有以下文件build.sbt。但是,这将为我的数据库表生成代码,并且不会包含数据库视图。我怎样才能获得生成的视图?

根据slick issue 1022,我认为可以这样做,但 API 看起来不一样,而且slick.codegen.SourceCodeGenerator 没有 getTablesdefaultTables 来包含视图名称。

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))
}

【问题讨论】:

  • 老实说 - 我在包含视图的 Slick 驱动的 DDL 方面没有取得多大成功。我最终在原始 SQL 中指定视图并将它们映射到类。我很想知道你是否会收到任何回复。

标签: scala sbt code-generation slick slick-3.0


【解决方案1】:

由于 Slick 生成器 API 中的许多更改,经过大量试验和错误,以下独立应用程序 Generator.scala 测试将在 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")
}

将此代码集成到build.sbt 中并不容易,因为需要定义一个外部自定义代码生成器文件,然后在编译实际项目之前从build.sbt 编译和运行它。可以在 github 项目slick-codegen-customization-example 中找到一个非常过时的示例,但请注意他们没有build.sbt,而是更高级的Build.scala

【讨论】:

  • 我已经成功地靠自己走了很远,但是当我看到 MTable 的其他用法时,我确信 Seq("TABLE","VIEW") 只是您想要的表和视图的实际名称的占位符包括,但不是元数据。还有一个小时我不会回来了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-28
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多