2011-03-26 10 views
9

ScalaQuery çalışıyorum bir veritabanı tablosu olup olmadığını nasıl bilebilirim, gerçekten harika. Scala sınıfını kullanarak veritabanı tablosunu tanımlayabilir ve kolayca sorgulayabilirim.ScalaQuery

Ancak aşağıdaki kodda, bir tablonun var olup olmadığını nasıl kontrol edebilirim, bu yüzden iki kez 'Table.ddl.create' çağrısı yapmam ve bu programı iki kez çalıştırdığımda bir istisna almam. ?

cevap

7

ScalaQuery sürümü 0.9.4 böyle MTable olarak org.scalaquery.meta paketinde yararlı SQL meta veri sarıcı sınıfların sayısını içerir: ScalaQuery test kodunda

http://scalaquery.org/doc/api/scalaquery-0.9.4/#org.scalaquery.meta.MTable

görebiliriz Bu sınıfların örnekleri kullanılmıştır. Özellikle, bkz. Org.scalaquery.test.MetaTest.

Bu küçük işlevi, tablo adıyla bilinen tüm bilinen tabloların bir haritasını vermek için yazdım. Bir SQL tablosu oluşturmak önce, kontrol edebilirim Şimdi

import org.scalaquery.meta.{MTable} 
def makeTableMap(dbsess: Session) : Map[String, MTable] = { 
    val tableList = MTable.getTables.list()(dbsess); 
    val tableMap = tableList.map{t => (t.name.name, t)}.toMap; 
    tableMap; 
} 

, "if (! TableMap.contains (tableName))".

+0

Bu yazı için teşekkürler! Bu oyunda asenkron önyükleme yapmak için harika bir yoldur! çerçeve (http://www.playframework.org/documentation/1.2.4/jobs). Şerefe, – egbutter

1

java.sql.DatabaseMetaData (Arabirim) ile. Veritabanınıza bağlı olarak, daha fazla veya daha az işlev uygulanabilir.

+0

Sanırım ScalaQuery yolu bunu yapamaz mı? –

+0

Hiçbir şey bulamadım ve bulduğum şeyden (Kullanıcı Kullanıcı Tablosunu (tiplerin)) genişletiyor, sanırım amaç erken yazmayı kullanmak.Dinamik tanımlı tabloları kendinizle nasıl sorunsuz bir şekilde bütünleştirebileceğinizi göremiyorum, ancak çoğu kez yansıma kullanmıyordum, bu yüzden belki de bir yol var ve bunu göremiyorum. Belgeler biraz zayıftır. Bazı “meta” sınıfları vardır, ancak bunları wiki'de veya blogda nasıl kullanacaklarını bulamadım. :) –

+0

Ben de bir şey bulamıyorum. Yani sanırım bu cevap. Ve sadece bir not, Session # metaData mevcut veritabanı oturumu java.sq.DatabaseMetaData alabilir. –

2

İşte bu parçacığı biraz eski Play Framework

import globals.DBGlobal 
import models.UsersTable 
import org.scalaquery.meta.MTable 
import org.scalaquery.session.Session 

import play.api.GlobalSettings 
import play.api.Application 

object Global extends GlobalSettings { 

    override def onStart(app: Application) { 

     DBGlobal.db.withSession { session : Session => 
      import org.scalaquery.session.Database.threadLocalSession 
      import org.scalaquery.ql.extended.PostgresDriver.Implicit._ 
      if (!makeTableMap(session).contains("tableName")) { 
       UsersTable.ddl.create(session) 
      } 
     } 
    } 

    def makeTableMap(dbsess: Session): Map[String, MTable] = { 
     val tableList = MTable.getTables.list()(dbsess) 
     val tableMap = tableList.map { 
     t => (t.name.name, t) 
    }.toMap 
     tableMap 
    } 
} 
7

için PostGreSQL DB kullanarak başlamak uygulamaya denetler tam bir çözüm, ama belki birisi bu yararlı bulacaksınız. Ben şahsen hezamu önerisini tercih ve KURU tutmaya şöyle uzatın

def create = db withSession { 
    if (!MTable.getTables.list.exists(_.name.name == MyTable.tableName)) 
     MyTable.ddl.create 
} 
+0

Teşekkürler, bu harika. Slick 2.1.x ile çalışır – Gavin

0

See also the related discussion here.: Bütün DAOs bu dahil

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

sadece örtülü oturumda ile tablolar oluşturabilirsiniz:

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

DAO'nuzda tanımlanmış bir tabloya bağlı olarak size doğru bir yanlışlık veren (Slick MTable.getTables always fails with Unexpected exception[JdbcSQLException: Invalid value 7 for parameter columnIndex [90008-60]]'dan alınan) aşağıdaki yöntemi uygulayabilirsiniz.

def checkTable() : Boolean = { 
     val action = MTable.getTables 
     val future = db.run(action) 
     val retVal = future map {result => 
      result map {x => x} 
     } 

     val x = Await.result(retVal, Duration.Inf) 

     if (x.length > 0) { 
      true 
     } else { 
      false 
     } 
     } 

Veya, bazı "GIVENTABLENAME" falan println yöntemle varsa kontrol edebilirsiniz: sizin db

 def printTable() ={ 
      val q = db.run(MTable.getTables) 
      println(Await.result(q, Duration.Inf).toList(0)) //prints first MTable element 
      println(Await.result(q, Duration.Inf).toList(1))//prints second MTable element 
      println(Await.result(q, Duration.Inf).toList.toString.contains("MTable(MQName(public.GIVENTABLENAME_pkey),INDEX,null,None,None,None)")) 
     } 

unutma

import slick.jdbc.meta._ 

Sonra diyoruz eklemek her zamanki @Inject() ile her yerden yöntemler. kullanarak, 2,4 ve play-slick 1.0.0 oynayın.

Şerefe,