]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- composite primary key is represented as a non-keyed set to allow for
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 13 Jul 2007 07:36:39 +0000 (07:36 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 13 Jul 2007 07:36:39 +0000 (07:36 +0000)
composite keys consisting of cols with the same name; occurs within a
Join.  helps inheritance scenarios formulate correct PK.
- ticket #185 reopened.  still need to get Join to produce a minmal PK for fk'ed columns

CHANGES
lib/sqlalchemy/sql.py
test/orm/abc_inheritance.py

diff --git a/CHANGES b/CHANGES
index 3cdb3cce0ba3ee90b8550f8629bd0f3cda90f599..bd71fe1b1fbca32dfb574e0af99cd48b0431b130 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -50,6 +50,9 @@
     - DynamicMetaData has been renamed to ThreadLocalMetaData.  the
       DynamicMetaData name is deprecated and is an alias for ThreadLocalMetaData
       or a regular MetaData if threadlocal=False
+    - composite primary key is represented as a non-keyed set to allow for 
+      composite keys consisting of cols with the same name; occurs within a
+      Join.  helps inheritance scenarios formulate correct PK.
     - some enhancements to "column targeting", the ability to match a column
       to a "corresponding" column in another selectable.  this affects mostly
       ORM ability to map to complex joins
index ff6aa5e2c1b3cdd2423dcc0b119240de8a4d0fc3..d1fc3fef17a8549a03fd258d3ce3d6e18ce28c18 100644 (file)
@@ -1618,6 +1618,25 @@ class ColumnCollection(util.OrderedProperties):
         # "True" value (i.e. a BinaryClause...)
         return col in util.Set(self)
 
+class ColumnSet(util.OrderedSet):
+    def contains_column(self, col):
+        return col in self
+        
+    def extend(self, cols):
+        for col in cols:
+            self.add(col)
+
+    def __add__(self, other):
+        return list(self) + list(other)
+
+    def __eq__(self, other):
+        l = []
+        for c in other:
+            for local in self:
+                if c.shares_lineage(local):
+                    l.append(c==local)
+        return and_(*l)
+            
 class FromClause(Selectable):
     """Represent an element that can be used within the ``FROM``
     clause of a ``SELECT`` statement.
@@ -1762,7 +1781,7 @@ class FromClause(Selectable):
             # TODO: put a mutex here ?  this is a key place for threading probs
             return
         self._columns = ColumnCollection()
-        self._primary_key = ColumnCollection()
+        self._primary_key = ColumnSet()
         self._foreign_keys = util.Set()
         self._orig_cols = {}
         for co in self._adjusted_exportable_columns():
index 766bbc5df17300fd477fe789df9e20e12bde2aa8..9b2928fbecc78369f765662c0587c690fdd0de9b 100644 (file)
@@ -84,9 +84,14 @@ def produce_test(parent, child, direction):
             class B(A):pass
             class C(B):pass
 
-            mapper(A, ta, polymorphic_on=abcjoin.c.type, select_table=abcjoin, polymorphic_identity="a")
-            mapper(B, tb, polymorphic_on=bcjoin.c.type, select_table=bcjoin, polymorphic_identity="b", inherits=A, inherit_condition=atob)
-            mapper(C, tc, polymorphic_identity="c", inherits=B, inherit_condition=btoc)
+            mapper(A, ta, polymorphic_on=abcjoin.c.type, select_table=abcjoin, polymorphic_identity="a", )
+            mapper(B, tb, polymorphic_on=bcjoin.c.type, select_table=bcjoin, polymorphic_identity="b", inherits=A, inherit_condition=atob,)
+            mapper(C, tc, polymorphic_identity="c", inherits=B, inherit_condition=btoc, )
+
+            #print "KEYS:"
+            #print [c.key for c in class_mapper(A).primary_key]
+            #print [c.key for c in class_mapper(B).primary_key]
+            #print [c.key for c in class_mapper(C).primary_key]
 
             parent_mapper = class_mapper({ta:A, tb:B, tc:C}[parent_table])
             child_mapper = class_mapper({ta:A, tb:B, tc:C}[child_table])
@@ -121,13 +126,14 @@ def produce_test(parent, child, direction):
             sess.clear()
 
             # assert result via direct get() of parent object
-            result = sess.query(parent_class).get(parent_obj.id)
+            # TODO: dual PK here is a temporary workaround until #185 is fixed again
+            result = sess.query(parent_class).get([parent_obj.id, parent_obj.id])
             assert result.id == parent_obj.id
             assert result.collection[0].id == child_obj.id
             if direction == ONETOMANY:
                 assert result.collection[1].id == child2.id
             elif direction == MANYTOONE:
-                result2 = sess.query(parent_class).get(parent2.id)
+                result2 = sess.query(parent_class).get([parent2.id, parent2.id])
                 assert result2.id == parent2.id
                 assert result2.collection[0].id == child_obj.id