2015-07-09 8 views
7

मेरे पास एक टेबल user_permissions है जिसमें 4612 कॉलम id और created_date के साथ 46 अनुमति कॉलम हैं।Slick - पूर्ण ऑब्जेक्ट या 22 से अधिक कॉलम अपडेट करें

class UserPermission(val id: Long, 
    val createdDate: Option[Timestamp], 
    val permission1: Boolean, 
    val permission2: Boolean, 
    ... 
    val permission46: Boolean) 

और चालाक मानचित्रण तालिका

class UserPermissions(tag: Tag) extends Table[UserPermission](tag, "users_permissions") { 
    def * = (
    id :: 
    createdDate :: 
    permission1 :: 
    permission2 :: 
    ... 
    permission46 :: 
    HNil).shaped <> (
    { case x => UserPermission(
     x(0), x(1), x(2), ... x(47)) 
    }, 
    { 
     UserPermission.unapply _ 
    } 
    } 
    ... <columns defined here> 
) 

अब मैं UserPermission सेट जो id द्वारा पहचाना जाता है अद्यतन करना चाहते: यह तालिका एक इसी UserPermissions वर्ग है। समारोह है कि मैंने यह है:

object UserPermissions { 
    val userPermissions = TableQuery[UserPermissions] 

    def update(userPermission: UserPermission)(implicit session: Session) = { 
    userPermissions.filter(_.id === userPermission.id.get).update(userPermission) 
    } 
} 

यह काम नहीं कर रहा है और फेंक अपवाद:

play.api.Application$$anon$1: Execution exception[[SQLServerException: Cannot update identity column 'id'.]] 

जो समझ में आता है के रूप में स्लिक द्वारा उत्पन्न एसक्यूएल है:

update "users_permissions" set "id" = ?, "created_date" = ?, ... 

समस्या 1 तो मेरी पहली समस्या यह है कि मैं एक पूर्ण UserPermission ऑब्जेक्ट अपडेट करने में असमर्थ हूं slickयदि मेरे पास इस समस्या का समाधान है तो यह बहुत अच्छा होगा।


जब से मैं पूरी वस्तु को अद्यतन करने में असमर्थ हूँ तो मैं कॉलम मैं तो अद्यतन एक अद्यतन क्वेरी सक्रिय करना चाहते हैं yield करने के लिए सोचा। कोड इस तरह दिखता है:

def update(obj: UserPermission)(implicit session: Session) = { 
    val query = for { 
     p <- userPermissions 
     if p.id === obj.id.get 
    } yield (p.permission1, p.permission2, ... p.permission46) 
    query.update(obj.permission1, obj.permission2, ... obj.permission46) 
} 

समस्या 2 अब चालाक query.update() समारोह में 46 कॉलम अपडेट नहीं हो रहा है। यह एक समय में केवल 22 कॉलम संभाल सकता है। मैं अपना UserPermissions ऑब्जेक्ट कैसे अपडेट कर सकता हूं?

एक बुरा समाधान मुझे लगता है कि 22 बार पहली बार अपडेट करना है, फिर 22 सेकंड, फिर तीसरे प्रश्न में 2। यह 3 डीबी अद्यतन प्रश्न होंगे जो मैं नहीं चाहता हूं।

मेरी समस्या का कोई समाधान?


निर्भरता हैं:


scalaVersion := "2.11.4" 

"com.typesafe.play" %% "play-slick" % "0.8.1" 
"com.typesafe.slick" %% "slick-extensions" % "2.1.0" 

उत्तर

1

समस्या 2 के लिए कुछ सुझाव:

  • क्या आप स्लिम 3.0 का उपयोग कर सकते हैं? ऐसा लगता है कि इस संस्करण में solution
  • क्या आप डेटाबेस के लेआउट को इस तरह से अनुमति दे सकते हैं अनुमतियाँ स्तंभों की बजाय पंक्तियां हैं? यह
+0

सुझाव प्रदान करने के लिए धन्यवाद। मैंने पोस्टिंग से पहले ही उन्हें पहले ही माना है लेकिन मैं इनमें से किसी भी को लागू नहीं कर सकता। 'प्ले' और 'स्लिक' को अपग्रेड करने के रूप में भविष्य के स्पिंट्स का हिस्सा हैं और टेबल लेआउट को उत्पादन प्रणालियों में बदला नहीं जा सकता है और कई अनुप्रयोगों को वर्तमान तालिका डिज़ाइन के साथ कसकर जोड़ दिया जाता है ताकि वे सभी प्रभावित हो जाएं। –

3

स्टीफन ज़ीगर, स्लिम लीड, said हम नहीं कर सकते थे।लेकिन उन्होंने सुझाव दिया है कि हम फ्लैट 22+ कॉलम मेज पर अनुमानों नेस्ट है

// 2 classes for the nested structure 
case class Part(i1: Int, i2: Int, i3: Int, i4: Int, i5: Int, i6: Int) 
case class Whole(id: Int, p1: Part, p2: Part, p3: Part, p4: Part) 

// Note that it's a Table[Int] -- we only map the primary key in * 
object T extends Table[Int]("t_wide") { 
    def id = column[Int]("id", O.PrimaryKey) 
    def p1i1 = column[Int]("p1i1") 
    def p1i2 = column[Int]("p1i2") 
    def p1i3 = column[Int]("p1i3") 
    def p1i4 = column[Int]("p1i4") 
    def p1i5 = column[Int]("p1i5") 
    def p1i6 = column[Int]("p1i6") 
    def p2i1 = column[Int]("p2i1") 
    def p2i2 = column[Int]("p2i2") 
    def p2i3 = column[Int]("p2i3") 
    def p2i4 = column[Int]("p2i4") 
    def p2i5 = column[Int]("p2i5") 
    def p2i6 = column[Int]("p2i6") 
    def p3i1 = column[Int]("p3i1") 
    def p3i2 = column[Int]("p3i2") 
    def p3i3 = column[Int]("p3i3") 
    def p3i4 = column[Int]("p3i4") 
    def p3i5 = column[Int]("p3i5") 
    def p3i6 = column[Int]("p3i6") 
    def p4i1 = column[Int]("p4i1") 
    def p4i2 = column[Int]("p4i2") 
    def p4i3 = column[Int]("p4i3") 
    def p4i4 = column[Int]("p4i4") 
    def p4i5 = column[Int]("p4i5") 
    def p4i6 = column[Int]("p4i6") 
    // This is just the default projection -- It doesn't have to contain all columns 
    def * = id 
    // Instead, we use nested tuples for a full projection: 
    def all = (
    id, 
    (p1i1, p1i2, p1i3, p1i4, p1i5, p1i6), 
    (p2i1, p2i2, p2i3, p2i4, p2i5, p2i6), 
    (p3i1, p3i2, p3i3, p3i4, p3i5, p3i6), 
    (p4i1, p4i2, p4i3, p4i4, p4i5, p4i6) 
) 
    // And override create_* to get the DDL for all columns. 
    // Yeah, this is ugly. It used to be much simpler in ScalaQuery. 
    // We can add a helper method to simplify it. 
    override def create_* = 
    all.shaped.packedNode.collect { 
     case Select(Ref(IntrinsicSymbol(in)), f: FieldSymbol) if in == this => f 
    }.toSeq.distinct 
} 

T.ddl.create 
// Insert into T.all. The extra ".shaped" call is needed because we cannot 
// get the types in an implicit conversion due to SI-3346 
T.all.shaped.insert(
    0, 
    (11, 12, 13, 14, 15, 16), 
    (21, 22, 23, 24, 25, 26), 
    (31, 32, 33, 34, 35, 36), 
    (41, 42, 43, 44, 45, 46) 
) 

// Get the nested tuples in a query 
val q1 = T.map(_.all) 
println(q1.first) 

// Map the result to the case classes 
val i2 = q1.mapResult { case (id, p1, p2, p3, p4) => 
    Whole(id, Part.tupled.apply(p1), Part.tupled.apply(p2), Part.tupled.apply(p3), Part.tupled.apply(p4)) 
} 
println(i2.first) 

जो version 3 के लिए एक सहित स्लिक पर अब एक test है। अद्यतन करने के लिए के रूप में:

val oData = Whole(0, 
    Part(11, 12, 13, 14, 15, 16), 
    Part(21, 22, 23, 24, 25, 26), 
    Part(31, 32, 33, 34, 35, 36), 
    Part(41, 42, 43, 44, 45, 46) 
) 
val oData2 = Whole(10, 
    Part(111, 12, 13, 14, 15, 16), 
    Part(121, 22, 23, 24, 25, 26), 
    Part(131, 32, 33, 34, 35, 36), 
    Part(141, 42, 43, 44, 45, 46) 
) 

ts.ddl.create 

ts.insert(oData) 
assertEquals(oData, ts.first) 

ts.filter(_.p1i2 === 12).update(oData2) 
assertEquals(oData2, ts.first) 

स्लिक के अनुमानों के साथ नेस्टेड वस्तुओं एक वस्तु है कि आप में लाने के लिए, या के साथ भाग लेने के लिए चपटा जा सकता है।

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