我正在使用Slick和Play Framework 2.1,并且遇到了一些问题。
鉴于以下实体...
package models
import scala.slick.driver.PostgresDriver.simple._
case class Account(id: Option[Long], email: String, password: String)
object Accounts extends Table[Account]("account") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def email = column[String]("email")
def password = column[String]("password")
def * = id.? ~ email ~ password <> (Account, Account.unapply _)
}
我需要为一个特定的数据库驱动程序导入一个包,但我想在测试中使用H2,而在生产环境中使用PostgreSQL。我该怎么做?
我成功地通过覆盖我的单元测试中的驱动程序设置来解决了这个问题:
package test
import org.specs2.mutable._
import play.api.test._
import play.api.test.Helpers._
import scala.slick.driver.H2Driver.simple._
import Database.threadLocalSession
import models.{Accounts, Account}
class AccountSpec extends Specification {
"An Account" should {
"be creatable" in {
Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") withSession {
Accounts.ddl.create
Accounts.insert(Account(None, "user@gmail.com", "Password"))
val account = for (account <- Accounts) yield account
account.first.id.get mustEqual 1
}
}
}
}
我不喜欢这个解决方案,想知道是否有一种优雅的方法编写与数据库无关的代码,以便在测试和生产中使用两种不同的数据库引擎?
我也不想使用演化,而是希望让Slick为我创建数据库表:
import play.api.Application
import play.api.GlobalSettings
import play.api.Play.current
import play.api.db.DB
import scala.slick.driver.PostgresDriver.simple._
import Database.threadLocalSession
import models.Accounts
object Global extends GlobalSettings {
override def onStart(app: Application) {
lazy val database = Database.forDataSource(DB.getDataSource())
database withSession {
Accounts.ddl.create
}
}
}
第一次启动应用程序时,一切都正常...然后,当我第二次启动应用程序时,由于表已经存在于PostgreSQL数据库中,它会崩溃。
话虽如此,我的最后两个问题是:
- 如何确定数据库表是否已经存在?
- 如何使上述
onStart
方法与数据库无关,以便我可以使用FakeApplication
测试我的应用程序?
play-slick
插件:https://dev59.com/6mYr5IYBdhLWcg3wdp4C#28174261 - Sebastien Lorber