当表不存在时如何仅执行DDL?

11
我正在使用Play Framework 2.1和MySQL的Slick 1.0。
我想控制ddl表的创建,以便仅在表不存在时才进行创建。也就是说,表只应在我第一次启动play时创建。
如何在Slick中实现?
3个回答

15

由于我喜欢单独控制表的创建并保持DRY原则,我倾向于在我的应用程序中添加一个实用方法:

def createIfNotExists(tables: TableQuery[_ <: Table[_]]*)(implicit session: Session) {
  tables foreach {table => if(MTable.getTables(table.baseTableRow.tableName).list.isEmpty) table.ddl.create}
}

然后您可以使用隐式会话创建您的表:

db withSession {
  implicit session =>
    createIfNotExists(table1, table2, ..., tablen)
}

这似乎是比被采纳的答案更健壮的解决方案。 - mo-seph

11

为了让其他人受益,SLICK提供了一个MTable对象,您可以使用它来计算数据库中存在的表的数量。

然后,如果它们不存在,您可以有条件地调用ddl。在下面的情况下,我希望有11个表+play_evolutions表。

import scala.slick.jdbc.meta._

 if (MTable.getTables.list().size < 12) {
        (Contacts.ddl ++ ThirdParties.ddl ++ Directorates.ddl ++ ServiceAreas.ddl ++ ICTServers.ddl
          ++ ICTServerDependencies.ddl ++ ICTSystems.ddl ++ ICTSystemDependencies.ddl ++ ICTSystemServerDependencies.ddl
              ++ CouncilServices.ddl ++ CouncilServiceDependencies.ddl).create
}

4
对于单个表格:if (MTable.getTables("test").list.isEmpty) Test.ddl.create - ArtemGr
1
在Slick 1.0中,您还可以通过调用Test.tableName来获取表名,在Slick 2.0中则是通过调用Test.baseTableRow.tableName。 - cvogt

8

我意识到这个问题是关于Slick 1的,但出于完整性考虑,在Slick 3中我做了以下操作:

  Await.result(createTableIfNotExists(tableQuery1, tableQuery2, tableQuery3), Duration.Inf)

  private def createTableIfNotExists(tables: TableQuery[_ <: Table[_]]*): Future[Seq[Unit]] = {
    Future.sequence(
      tables map { table =>
        db.run(MTable.getTables(table.baseTableRow.tableName)).flatMap { result =>
          if (result.isEmpty) {
            db.run(table.schema.create)
          } else {
            Future.successful(())
          }
        }
      }
    )
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接