summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-07-13 07:36:39 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-07-13 07:36:39 +0000
commitde220677418653257b0068c71e87698e8978796b (patch)
tree3c5d19de610252e59e9c5734395d4e6cb789f568
parent94d81c84cefee51485c26d79b028aa85e61b147c (diff)
downloadsqlalchemy-de220677418653257b0068c71e87698e8978796b.tar.gz
- 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. - ticket #185 reopened. still need to get Join to produce a minmal PK for fk'ed columns
-rw-r--r--CHANGES3
-rw-r--r--lib/sqlalchemy/sql.py21
-rw-r--r--test/orm/abc_inheritance.py16
3 files changed, 34 insertions, 6 deletions
diff --git a/CHANGES b/CHANGES
index 3cdb3cce0..bd71fe1b1 100644
--- 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
diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py
index ff6aa5e2c..d1fc3fef1 100644
--- a/lib/sqlalchemy/sql.py
+++ b/lib/sqlalchemy/sql.py
@@ -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():
diff --git a/test/orm/abc_inheritance.py b/test/orm/abc_inheritance.py
index 766bbc5df..9b2928fbe 100644
--- a/test/orm/abc_inheritance.py
+++ b/test/orm/abc_inheritance.py
@@ -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