2015-11-26 4 views
13

В 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 И ТОЛЬКО ЕСЛИ он еще не существует?

ответ

4

Это то, что я могу сделать для нескольких таблиц, с гладкой 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) 
4

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

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

С 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 
+1

Я продолжаю получать ошибку контекста выполнения для этого, ошибка исчезает, если я импортирую 'scala.concurrent.ExecutionContext.Implicits.global', но тогда таблица не создается. Как я могу это решить? – JoshSGman

3

Как JoshSGoman comment баллов из о answer of Mike-s, таблица не создается. Мне удалось заставить его работать, слегка изменив код первого ответа в:

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 
+0

Зачем нам нужно дважды объявлять db.run? Не должно ли coffees.schema.create работать в этом контексте? – JoshSGman

Смежные вопросы