Подтвердить что ты не робот

Scala Слайк, как создать схему ТОЛЬКО, если она не существует

В Scala Slick можно создать схему базы данных со следующим:

val schema = coffees.schema ++ suppliers.schema
db.run(DBIO.seq(
  schema.create
))

Внизу этой страницы документации http://slick.typesafe.com/doc/3.0.0/schemas.html

Однако, если схема базы данных уже существует, это вызывает исключение.

Есть ли нормальный способ или правильный способ создания схемы IF и ТОЛЬКО ЕСЛИ он еще не существует?

4b9b3361

Ответ 1

Это то, что я делаю для нескольких таблиц, с гладкими 3.1.1 и Postgres

import slick.driver.PostgresDriver.api._
import slick.jdbc.meta.MTable
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global

val t1 = TableQuery[Table1]
val t2 = TableQuery[Table2]
val t3 = TableQuery[Table3]
val tables = List(t1, t2, t3)

val existing = db.run(MTable.getTables)
val f = existing.flatMap( v => {
    val names = v.map(mt => mt.name.name)
    val createIfNotExist = tables.filter( table =>
        (!names.contains(table.baseTableRow.tableName))).map(_.schema.create)
    db.run(DBIO.sequence(createIfNotExist))
})
Await.result(f, Duration.Inf)

Ответ 2

почему бы вам просто не проверить существование до create?

val schema = coffees.schema ++ suppliers.schema
db.run(DBIO.seq(
  if (!MTable.getTables.list.exists(_.name.name == MyTable.tableName)){
    schema.create
  }
))

Ответ 3

С Slick 3.0, Mtable.getTables - это DBAction, поэтому что-то вроде этого будет работать:

val coffees = TableQuery[Coffees]
try {
  Await.result(db.run(DBIO.seq(
    MTable.getTables map (tables => {
      if (!tables.exists(_.name.name == coffees.baseTableRow.tableName))
        coffees.schema.create
    })
  )), Duration.Inf)
} finally db.close

Ответ 4

Как комментарий JoshSGoman указывает на ответ Майка, таблица не создается. Мне удалось заставить его работать, слегка изменив первый код ответа:

val coffees = TableQuery[Coffees]

try {
  def createTableIfNotInTables(tables: Vector[MTable]): Future[Unit] = {
    if (!tables.exists(_.name.name == events.baseTableRow.tableName)) {
      db.run(coffees.schema.create)
    } else {
      Future()
    }
  }

  val createTableIfNotExist: Future[Unit] = db.run(MTable.getTables).flatMap(createTableIfNotInTables)

  Await.result(createTableIfNotExist, Duration.Inf)
} finally db.close

Со следующими импортами:

import slick.jdbc.meta.MTable
import slick.driver.SQLiteDriver.api._

import scala.concurrent.{Await, Future}
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global