summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-06-04 16:21:25 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-06-04 16:21:25 -0400
commit51e1019f610f083ac4d8c850589cdf52cff044da (patch)
treedb56526f4fd2fb9d0e63c6dbef151075f248ca5c
parentfa3d18a47cb6f307b18da880a5f8f4c06a6023b4 (diff)
downloadsqlalchemy-51e1019f610f083ac4d8c850589cdf52cff044da.tar.gz
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)
-rw-r--r--lib/sqlalchemy/orm/strategies.py3
-rw-r--r--lib/sqlalchemy/orm/util.py5
-rw-r--r--lib/sqlalchemy/sql/expression.py19
3 files changed, 19 insertions, 8 deletions
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index cabfb35b9..baaf4cb92 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 bd8228f2c..3da6e89e3 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 edab9e290..633a3ddba 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,