2011-03-26 19 views
9

में डेटाबेस तालिका मौजूद है या नहीं, मैं ScalaQuery कोशिश कर रहा हूं, यह वाकई अद्भुत है। मैं स्कैला वर्ग का उपयोग कर डेटाबेस तालिका को परिभाषित कर सकता हूं, और इसे आसानी से पूछता हूं।मुझे कैसे पता चलेगा कि ScalaQuery

लेकिन मैं जानना चाहता हूं, निम्न कोड में, मैं कैसे जांच सकता हूं कि कोई तालिका मौजूद है या नहीं, इसलिए मैं दो बार 'table.ddl.create' नहीं कहूंगा और जब मैं इस प्रोग्राम को दो बार चलाता हूं तो अपवाद प्राप्त करूंगा ?

object Users extends Table[(Int, String, String)]("Users") { 
    def id = column[Int]("id") 
    def first = column[String]("first") 
    def last = column[String]("last") 
    def * = id ~ first ~ last 
} 

object Main 
{ 
    val database = Database.forURL("jdbc:sqlite:sample.db", driver = "org.sqlite.JDBC") 

    def main(args: Array[String]) { 
     database withSession { 
      // How could I know table Users is alrady in the DB? 
      if (???) { 
       Users.ddl.create 
      } 
     } 
    } 
} 

उत्तर

7

ScalaQuery संस्करण 0.9.4 ऐसे MTable रूप org.scalaquery.meta पैकेज में सहायक एसक्यूएल मेटाडाटा आवरण कक्षाएं, की एक संख्या में शामिल हैं:

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

ScalaQuery के लिए परीक्षण कोड में, हम देख सकते हैं इन वर्गों के उदाहरणों का उपयोग किया जा रहा है। विशेष रूप से, org.scalaquery.test.MetaTest देखें।

मैंने टेबल नाम से की जाने वाली सभी ज्ञात तालिकाओं का नक्शा देने के लिए यह छोटा फ़ंक्शन लिखा था।

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; 
} 

तो अब, इससे पहले कि मैं एक एसक्यूएल तालिका बनाने, मैं जाँच कर सकते हैं "अगर (! TableMap.contains (TableName))"।

+0

इस पोस्ट के लिए धन्यवाद! नाटक पर एसिंक्रोनस बूटस्ट्रैप बनाने का यह एक शानदार तरीका है! ढांचा (http://www.playframework.org/documentation/1.2.4/jobs)। चीयर्स, – egbutter

1

java.sql.DatabaseMetaData (इंटरफेस) के साथ। आपके डेटाबेस के आधार पर, कम या ज्यादा फ़ंक्शन लागू किए जा सकते हैं।

+0

तो मुझे लगता है कि कोई स्कैलाक्वायर तरीका ऐसा नहीं कर सकता है? –

+0

मुझे कुछ भी नहीं मिला, और जो मैंने पाया ('उपयोगकर्ता तालिका [(प्रकार का टुपल)] बढ़ाता है), मुझे लगता है कि लक्ष्य प्रारंभिक टाइपिंग का उपयोग करना है।मैं नहीं देख सकता कि आप गतिशील परिभाषित तालिकाओं को आसानी से कैसे एकीकृत कर सकते हैं, लेकिन मैंने अक्सर प्रतिबिंब का उपयोग नहीं किया, इसलिए शायद एक तरीका है, और मैं इसे देख नहीं सकता। दस्तावेज थोड़ा सा दुबला है। कुछ 'मेटा' वर्ग हैं, लेकिन मुझे उदाहरण नहीं मिला कि विकी या ब्लॉग में उनका उपयोग कैसे किया जाए। :) –

+0

मुझे कुछ भी नहीं मिला है। तो मुझे लगता है कि यह जवाब है। और सिर्फ एक नोट, सत्र # मेटाडेटा को वर्तमान डेटाबेस सत्र का java.sq.DatabaseMetaData मिल सकता है। –

2

यहाँ एक पूर्ण समाधान है कि आवेदन पर जांच करता है PlayFramework

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

के लिए एक PostgreSQL डीबी का उपयोग कर यह धागा थोड़ा पुराना है शुरू है, लेकिन शायद किसी को यह उपयोगी मिल जाएगा। मेरे सभी DAOs में शामिल हैं:

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

धन्यवाद, यह बहुत अच्छा है। Slick 2.1.x के साथ काम करता है – Gavin

0

See also the related discussion here. मैं व्यक्तिगत रूप से hezamu के सुझाव को पसंद करते हैं और यह विस्तार के रूप में यह सूखा रखने के लिए इस प्रकार है:

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

तो फिर तुम सिर्फ अंतर्निहित सत्र के साथ अपने टेबल बना सकते हैं:

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

आप अपने डीएओ में निम्नलिखित विधि को लागू कर सकते हैं (Slick MTable.getTables always fails with Unexpected exception[JdbcSQLException: Invalid value 7 for parameter columnIndex [90008-60]] से लिया गया) जो आपको एक वास्तविक तालिका के आधार पर सही साबित करता है

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 
     } 
     } 

या, आप देख सकते हैं कि कुछ "GIVENTABLENAME" या कुछ और println विधि के साथ मौजूद है:: अपने 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)")) 
     } 

मत भूलना जोड़ने के लिए

import slick.jdbc.meta._ 

फिर फोन सामान्य @Inject() के साथ कहीं से भी तरीकों। का उपयोग 2.4 और प्ले-स्लिक 1.0.0 का उपयोग करना।

चीयर्स,

संबंधित मुद्दे