2015-11-26 19 views
13

Trong Scala Slick, một giản đồ cơ sở dữ liệu có thể được tạo ra với những điều sau đây:Scala Slick, làm thế nào để tạo ra Schema CHỈ nếu nó không tồn tại

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

Từ dưới cùng của trang tài liệu này http://slick.typesafe.com/doc/3.0.0/schemas.html

Tuy nhiên , nếu lược đồ cơ sở dữ liệu đã tồn tại thì điều này sẽ ném một ngoại lệ.

Có cách nào bình thường hoặc đúng cách để tạo lược đồ NẾU VÀ CHỈ NẾU nó không tồn tại?

Trả lời

4

Đây là những gì tôi làm cho nhiều bảng, với trơn 3.1.1 và 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

tại sao bạn không chỉ cần kiểm tra sự tồn tại trước create?

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

Với Slick 3.0, Mtable.getTables là một DBAction nên một cái gì đó như thế này sẽ làm việc:

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

Tôi tiếp tục nhận được lỗi ngữ cảnh thực hiện cho việc này, lỗi sẽ biến mất nếu tôi nhập 'scala.concurrent.ExecutionContext.Implicits.global' nhưng sau đó bảng sẽ không được tạo. Làm thế nào tôi có thể giải quyết điều đó? – JoshSGman

3

Như JoshSGoman comment điểm ra về answer of Mike-s, bảng không được tạo ra. Tôi quản lý để làm cho nó hoạt động bằng cách hơi thay đổi mã câu trả lời đầu tiên của:

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 

Với hàng nhập khẩu như sau:

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

Tại sao chúng ta cần khai báo db.run hai lần? Coffees.schema.create có nên vẫn hoạt động trong bối cảnh này không? – JoshSGman

Các vấn đề liên quan