From: Mike Bayer Date: Tue, 4 Jun 2013 20:21:25 +0000 (-0400) Subject: here's the flat join thing. it just works. Changing the existing compiled SQL... X-Git-Tag: rel_0_9_0b1~294^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=51e1019f610f083ac4d8c850589cdf52cff044da;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git here's the flat join thing. it just works. Changing the existing compiled SQL assertions might even be most of the tests we need (though dedicated sql tests would be needed anyway) --- diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index cabfb35b96..baaf4cb929 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -1089,7 +1089,8 @@ class JoinedLoader(AbstractRelationshipLoader): to_adapt = with_poly_info.entity else: to_adapt = orm_util.AliasedClass(self.mapper, - use_mapper_path=True) + use_mapper_path=True, + flat=True) clauses = orm_util.ORMAdapter( to_adapt, equivalents=self.mapper._equivalent_columns, diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index bd8228f2c1..3da6e89e3f 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -493,6 +493,7 @@ class AliasedClass(object): """ def __init__(self, cls, alias=None, name=None, + flat=False, adapt_on_names=False, # TODO: None for default here? with_polymorphic_mappers=(), @@ -501,7 +502,7 @@ class AliasedClass(object): use_mapper_path=False): mapper = _class_to_mapper(cls) if alias is None: - alias = mapper._with_polymorphic_selectable.alias(name=name) + alias = mapper._with_polymorphic_selectable.alias(name=name, flat=flat) self._aliased_insp = AliasedInsp( self, mapper, @@ -837,7 +838,7 @@ def with_polymorphic(base, classes, selectable=False, _with_polymorphic_args(classes, selectable, innerjoin=innerjoin) if aliased: - selectable = selectable.alias() + selectable = selectable.alias(flat=True) return AliasedClass(base, selectable, with_polymorphic_mappers=mappers, diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index edab9e2901..633a3ddba7 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -795,7 +795,7 @@ def intersect_all(*selects, **kwargs): return CompoundSelect(CompoundSelect.INTERSECT_ALL, *selects, **kwargs) -def alias(selectable, name=None): +def alias(selectable, name=None, flat=False): """Return an :class:`.Alias` object. An :class:`.Alias` represents any :class:`.FromClause` @@ -2634,7 +2634,7 @@ class FromClause(Selectable): return Join(self, right, onclause, True) - def alias(self, name=None): + def alias(self, name=None, flat=False): """return an alias of this :class:`.FromClause`. This is shorthand for calling:: @@ -3971,7 +3971,7 @@ class Join(FromClause): def bind(self): return self.left.bind or self.right.bind - def alias(self, name=None): + def alias(self, name=None, flat=False): """return an alias of this :class:`.Join`. Used against a :class:`.Join` object, @@ -3999,7 +3999,16 @@ class Join(FromClause): aliases. """ - return self.select(use_labels=True, correlate=False).alias(name) + if flat: + assert name is None, "Can't send name argument with flat" + left_a, right_a = self.left.alias(), self.right.alias() + adapter = sqlutil.ClauseAdapter(left_a).\ + chain(sqlutil.ClauseAdapter(right_a)) + + return left_a.join(right_a, + adapter.traverse(self.onclause), isouter=self.isouter) + else: + return self.select(use_labels=True, correlate=False).alias(name) @property def _hide_froms(self): @@ -4129,7 +4138,7 @@ class CTE(Alias): self._restates = _restates super(CTE, self).__init__(selectable, name=name) - def alias(self, name=None): + def alias(self, name=None, flat=False): return CTE( self.original, name=name,