播放框架和Slick自动数据库创建 [英] Play framework and Slick automatic database creation
问题描述
我正在使用play 2.4和Slick 3,是否可以自动生成ddl脚本,它是进化的?
I'm using play 2.4 and Slick 3, Is it possible to generate automatically ddl scripts, it is evolutions?
我在官方文档中找到了一些脚本,但是应该将其放置在play框架中的什么位置? http://slick.typesafe.com/doc/3.1.0/schemas.html
In official docs I found some scripts, but where should I place it in play framework? http://slick.typesafe.com/doc/3.1.0/schemas.html
您知道有任何库来管理代码中的演化而不编写普通的SQL吗?
Do you know any libs to manage evolutions in code to not write plain SQL?
推荐答案
我使用PostgresDriver进行了一些变通,创建了模块,该模块将DDL打印到文件中.每次更改代码后,我只需要替换1.sql或以后修改下一个Evolution脚本即可:
I made some workaround with PostgresDriver, I've created module, that prints DDL to file. After every code change I just need to replace 1.sql or later modify next evolution scripts:
ComputersDatabaseModule.scala
package bootstrap
import com.google.inject.AbstractModule
import play.api.{Mode, Play}
class ComputersDatabaseModule extends AbstractModule {
protected def configure() = {
bind(classOf[CreateDDL]).asEagerSingleton()
bind(classOf[InitialData]).asEagerSingleton()
}
}
CreateDDL.scala
package bootstrap
import java.io.PrintWriter
import javax.inject.Inject
import dao.{CompaniesMapping, ComputersMapping}
import play.api.db.slick.{HasDatabaseConfigProvider, DatabaseConfigProvider}
import slick.driver.JdbcProfile
/**
* Creates DDL script
*/
private[bootstrap] class CreateDDL @Inject()(protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] with
ComputersMapping with CompaniesMapping {
def createDDLScript() = {
import slick.driver.PostgresDriver.api._
val allSchemas = companies.schema ++ computers.schema
val writer = new PrintWriter("target/migration_ddl.sql")
writer.write("# --- !Ups\n\n")
allSchemas.createStatements.foreach { s => writer.write(s + ";\n") }
writer.write("\n\n# --- !Downs\n\n")
allSchemas.dropStatements.foreach { s => writer.write(s + ";\n") }
writer.close()
}
createDDLScript()
}
ComputersDAO.scala
package dao
import java.util.Date
import javax.inject.{Inject, Singleton}
import models.{Company, Computer, Page}
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import slick.driver.JdbcProfile
import scala.concurrent.Future
trait ComputersMapping { self: HasDatabaseConfigProvider[JdbcProfile] =>
import driver.api._
class Computers(tag: Tag) extends Table[Computer](tag, "COMPUTER") {
implicit val dateColumnType = MappedColumnType.base[Date, Long](d => d.getTime, d => new Date(d))
def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
def name = column[String]("NAME")
def introduced = column[Option[Date]]("INTRODUCED")
def discontinued = column[Option[Date]]("DISCONTINUED")
def companyId = column[Option[Long]]("COMPANY_ID")
def * = (id.?, name, introduced, discontinued, companyId) <> (Computer.tupled, Computer.unapply)
}
val computers = TableQuery[Computers]
}
@Singleton()
class ComputersDAO @Inject() (protected val dbConfigProvider: DatabaseConfigProvider) extends CompaniesMapping with ComputersMapping
with HasDatabaseConfigProvider[JdbcProfile] {
import driver.api._
/** Retrieve a computer from the id. */
def findById(id: Long): Future[Option[Computer]] =
db.run(computers.filter(_.id === id).result.headOption)
/** Count all computers. */
def count(): Future[Int] = {
// this should be changed to
// db.run(computers.length.result)
// when https://github.com/slick/slick/issues/1237 is fixed
db.run(computers.map(_.id).length.result)
}
/** Count computers with a filter. */
def count(filter: String): Future[Int] = {
db.run(computers.filter { computer => computer.name.toLowerCase like filter.toLowerCase }.length.result)
}
/** Return a page of (Computer,Company) */
def list(page: Int = 0, pageSize: Int = 10, orderBy: Int = 1, filter: String = "%"): Future[Page[(Computer, Company)]] = {
val offset = pageSize * page
val query =
(for {
(computer, company) <- computers joinLeft companies on (_.companyId === _.id)
if computer.name.toLowerCase like filter.toLowerCase
} yield (computer, company.map(_.id), company.map(_.name)))
.drop(offset)
.take(pageSize)
for {
totalRows <- count(filter)
list = query.result.map { rows => rows.collect { case (computer, id, Some(name)) => (computer, Company(id, name)) } }
result <- db.run(list)
} yield Page(result, page, offset, totalRows)
}
/** Insert a new computer. */
def insert(computer: Computer): Future[Unit] =
db.run(computers += computer).map(_ => ())
/** Insert new computers. */
def insert(computers: Seq[Computer]): Future[Unit] =
db.run(this.computers ++= computers).map(_ => ())
/** Update a computer. */
def update(id: Long, computer: Computer): Future[Unit] = {
val computerToUpdate: Computer = computer.copy(Some(id))
db.run(computers.filter(_.id === id).update(computerToUpdate)).map(_ => ())
}
/** Delete a computer. */
def delete(id: Long): Future[Unit] =
db.run(computers.filter(_.id === id).delete).map(_ => ())
}
添加配置( application.config ):
play.modules.enabled += "bootstrap.ComputersDatabaseModule"
这篇关于播放框架和Slick自动数据库创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!