【问题标题】:Slick: create databaseSlick:创建数据库
【发布时间】:2026-02-05 01:10:01
【问题描述】:

如果数据库尚不存在,有没有办法巧妙地创建数据库?

Database.forURL("jdbc:mysql://127.0.0.1/database", driver = "com.mysql.jdbc.Driver", user = "root") withSession {
  // create tables, insert data
}

"database" 不存在,所以我想要 slick 为我创建它。有任何想法吗?谢谢。

【问题讨论】:

    标签: scala slick


    【解决方案1】:

    上面的答案与不推荐使用 withSession 的 Slick 2.x 相关, 所以这就是使用 Slick 3.0.0 API 完成的方式:

    import scala.concurrent.Await
    import scala.concurrent.duration._
    import org.postgresql.util.PSQLException
    import slick.driver.PostgresDriver
    import slick.driver.PostgresDriver.api._
    
    object SlickPGUtils {
    
      private val actionTimeout = 10 second
      private val driver = "org.postgresql.Driver"
    
      def createDb(host: String, port: Int, dbName: String, user: String, pwd: String) = {
        val onlyHostNoDbUrl = s"jdbc:postgresql://$host:$port/"
        using(Database.forURL(onlyHostNoDbUrl, user = user, password = pwd, driver = driver)) { conn =>
          Await.result(conn.run(sqlu"CREATE DATABASE #$dbName"), actionTimeout)
        }
      }
    
      def dropDb(host: String, port: Int, dbName: String, user: String, pwd: String) = {
        val onlyHostNoDbUrl = s"jdbc:postgresql://$host:$port/"
        try {
          using(Database.forURL(onlyHostNoDbUrl, user = user, password = pwd, driver = driver)) { conn =>
            Await.result(conn.run(sqlu"DROP DATABASE #$dbName"), actionTimeout)
          }
        } catch {
          // ignore failure due to db not exist
          case e:PSQLException => if (e.getMessage.equals(s""""database "$dbName" does not exist""")) {/* do nothing */}
          case e:Throwable => throw e // escalate other exceptions
        }
      }
    
      private def using[A <: {def close() : Unit}, B](resource: A)(f: A => B): B =
        try {
          f(resource)
        } finally {
          Try {
            resource.close()
          }.failed.foreach(err => throw new Exception(s"failed to close $resource", err))
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以仅使用 "jdbc:mysql://localhost/" 作为 JDBC URL 连接到数据库引擎,然后发出纯 SQL create database 查询:

      import scala.slick.driver.MySQLDriver.simple._
      import scala.slick.jdbc.{StaticQuery => Q}
      
      object Main extends App
      {
          Database.forURL("jdbc:mysql://localhost/", driver = "com.mysql.jdbc.Driver") withSession {
              implicit session =>
                  Q.updateNA("CREATE DATABASE `dataBaseName`").execute
              .
              .
              .
          }
      }
      

      【讨论】:

      • 谢谢@Răzvan,你能告诉我如何首先检查数据库是否存在吗?此外,在 slick 3 中不推荐使用 withSession,我仍然没有弄清楚新 API 中的等价物是什么。有什么想法吗?
      • 您可以使用*.com/a/838993/750216。对于 withSession,请参阅:grokbase.com/t/gg/scalaquery/15250knfya/…