From: Mike Bayer Date: Thu, 15 Sep 2011 21:58:01 +0000 (-0400) Subject: - Another previously unknown feature from 0.6, synonyms X-Git-Tag: rel_0_7_3~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40ffa5a8046e95e6c149c90e8cf7408b99e33c46;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Another previously unknown feature from 0.6, synonyms of relationship() can again be passed to join(). --- diff --git a/CHANGES b/CHANGES index f98071715a..58525eb75a 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,9 @@ CHANGES in 0.7, can now make a synonym() of a synonym() again. + - Another previously unknown feature from 0.6, synonyms + of relationship() can again be passed to join(). + - Identity map .discard() uses dict.pop(,None) internally instead of "del" to avoid KeyError/warning during a non-determinate gc teardown [ticket:2267] diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py index 6385d40e29..302c374c3c 100644 --- a/lib/sqlalchemy/orm/descriptor_props.py +++ b/lib/sqlalchemy/orm/descriptor_props.py @@ -355,6 +355,10 @@ class SynonymProperty(DescriptorProperty): def _proxied_property(self): return getattr(self.parent.class_, self.name).property + @property + def _synonym_resolved_property(self): + return self._proxied_property + def _comparator_factory(self, mapper): prop = self._proxied_property diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 1b1eef6d25..813c655fa2 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -266,6 +266,9 @@ class RelationshipProperty(StrategizedProperty): self.backref = None else: self.backref = backref + @property + def _synonym_resolved_property(self): + return self def instrument_class(self, mapper): attributes.register_descriptor( diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 6ef6c3b573..20c8280d14 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -1582,16 +1582,16 @@ class Query(object): if isinstance(onclause, interfaces.PropComparator): if right_entity is None: - right_entity = onclause.property.mapper + right_entity = onclause.property._synonym_resolved_property.mapper of_type = getattr(onclause, '_of_type', None) if of_type: right_entity = of_type else: - right_entity = onclause.property.mapper + right_entity = onclause.property._synonym_resolved_property.mapper left_entity = onclause.parententity - prop = onclause.property + prop = onclause.property._synonym_resolved_property if not isinstance(onclause, attributes.QueryableAttribute): onclause = prop diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index d778bef3d7..d7c8b20a2f 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -357,7 +357,7 @@ class _ORMJoin(expression.Join): if prop: pj, sj, source, dest, \ - secondary, target_adapter = prop._create_joins( + secondary, target_adapter = prop._synonym_resolved_property._create_joins( source_selectable=adapt_from, dest_selectable=adapt_to, source_polymorphic=True, diff --git a/test/orm/test_joins.py b/test/orm/test_joins.py index 7e47c55bf8..af35912f79 100644 --- a/test/orm/test_joins.py +++ b/test/orm/test_joins.py @@ -386,6 +386,24 @@ class JoinTest(QueryTest, AssertsCompiledSQL): "ON addresses.id = orders.address_id" ) + def test_join_on_synonym(self): + + class User(object): + pass + class Address(object): + pass + users, addresses = (self.tables.users, self.tables.addresses) + mapper(User, users, properties={ + 'addresses':relationship(Address), + 'ad_syn':synonym("addresses") + }) + mapper(Address, addresses) + self.assert_compile( + Session().query(User).join(User.ad_syn), + "SELECT users.id AS users_id, users.name AS users_name " + "FROM users JOIN addresses ON users.id = addresses.user_id" + ) + def test_multi_tuple_form(self): """test the 'tuple' form of join, now superseded by the two-element join() form. diff --git a/test/orm/test_query.py b/test/orm/test_query.py index 73298e8dff..ec4a328e0b 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -1793,8 +1793,6 @@ class SynonymTest(QueryTest): }) mapper(Keyword, keywords) - @testing.fails_if(lambda: True, "0.7 regression, may not support " - "synonyms for relationship") def test_joins(self): User = self.classes.User