From: Mike Bayer Date: Thu, 2 Apr 2009 14:53:28 +0000 (+0000) Subject: - Fixed bug in relation(), introduced in 0.5.3, X-Git-Tag: rel_0_5_4~39 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=13cc1279f83f84b02d19ed8def0fcee09e9fddb1;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Fixed bug in relation(), introduced in 0.5.3, whereby a self referential relation from a base class to a joined-table subclass would not configure correctly. --- diff --git a/CHANGES b/CHANGES index ab264511c7..bb921bb524 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,11 @@ CHANGES - Fixed another location where autoflush was interfering with session.merge(). autoflush is disabled completely for the duration of merge() now. [ticket:1360] + + - Fixed bug in relation(), introduced in 0.5.3, + whereby a self referential relation + from a base class to a joined-table subclass would + not configure correctly. - sql - ``sqlalchemy.extract()`` is now dialect sensitive and can diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index b9fe1c0f8a..398cbe5d98 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -1021,7 +1021,11 @@ class RelationProperty(StrategizedProperty): def _refers_to_parent_table(self): - return self.parent.mapped_table is self.target + for c, f in self.synchronize_pairs: + if c.table is f.table: + return True + else: + return False def _is_self_referential(self): return self.mapper.common_parent(self.parent) diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index a8de5c6352..36357faf50 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -45,6 +45,7 @@ def find_join_source(clauses, join_to): return i, f else: return None, None + def find_tables(clause, check_columns=False, include_aliases=False, include_joins=False, include_selects=False): """locate Table objects within the given expression.""" diff --git a/test/orm/inheritance/polymorph2.py b/test/orm/inheritance/polymorph2.py index c5b9b3fde6..569fdd52e3 100644 --- a/test/orm/inheritance/polymorph2.py +++ b/test/orm/inheritance/polymorph2.py @@ -8,6 +8,8 @@ from sqlalchemy import util from sqlalchemy.orm import * from testlib import * from testlib import fixtures +from orm import _base +from testlib.testing import eq_ class AttrSettable(object): def __init__(self, **kwargs): @@ -610,7 +612,50 @@ class RelationTest7(ORMTest): for p in r: assert p.car_id == p.car.car_id +class RelationTest8(ORMTest): + def define_tables(self, metadata): + global taggable, users + taggable = Table('taggable', metadata, + Column('id', Integer, primary_key=True), + Column('type', String(30)), + Column('owner_id', Integer, ForeignKey('taggable.id')), + ) + users = Table ('users', metadata, + Column('id', Integer, ForeignKey('taggable.id'), primary_key=True), + Column('data', String(50)), + ) + + def test_selfref_onjoined(self): + class Taggable(_base.ComparableEntity): + pass + + class User(Taggable): + pass + + mapper( Taggable, taggable, polymorphic_on=taggable.c.type, polymorphic_identity='taggable', properties = { + 'owner' : relation (User, + primaryjoin=taggable.c.owner_id ==taggable.c.id, + remote_side=taggable.c.id + ), + }) + + + mapper(User, users, inherits=Taggable, polymorphic_identity='user', + inherit_condition=users.c.id == taggable.c.id, + ) + + + u1 = User(data='u1') + t1 = Taggable(owner=u1) + sess = create_session() + sess.add(t1) + sess.flush() + sess.expunge_all() + eq_( + sess.query(Taggable).order_by(Taggable.id).all(), + [User(data='u1'), Taggable(owner=User(data='u1'))] + ) class GenerativeTest(TestBase, AssertsExecutionResults): def setUpAll(self):