diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-10-15 17:21:38 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-10-15 17:21:38 -0400 |
| commit | c307df6596dab489109cd216665cf30006b70d13 (patch) | |
| tree | 4ce669b36759f8289d959c0e7e92b776b77d1865 /lib/sqlalchemy | |
| parent | 3510e38a772a2e48a8bb4b0a4efc6479034f649e (diff) | |
| download | sqlalchemy-c307df6596dab489109cd216665cf30006b70d13.tar.gz | |
- [feature] "scalar" selects now have a WHERE method
to help with generative building. Also slight adjustment
regarding how SS "correlates" columns; the new methodology
no longer applies meaning to the underlying
Table column being selected. This improves
some fairly esoteric situations, and the logic
that was there didn't seem to have any purpose.
- [feature] Some support for auto-rendering of a
relationship join condition based on the mapped
attribute, with usage of core SQL constructs.
E.g. select([SomeClass]).where(SomeClass.somerelationship)
would render SELECT from "someclass" and use the
primaryjoin of "somerelationship" as the WHERE
clause. This changes the previous meaning
of "SomeClass.somerelationship" when used in a
core SQL context; previously, it would "resolve"
to the parent selectable, which wasn't generally
useful. Related to [ticket:2245].
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/orm/properties.py | 23 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/util.py | 2 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/expression.py | 14 |
3 files changed, 31 insertions, 8 deletions
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index f8288f5fb..048b4fad3 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -350,6 +350,8 @@ class RelationshipProperty(StrategizedProperty): """ + _of_type = None + def __init__(self, prop, mapper, of_type=None, adapter=None): """Construction of :class:`.RelationshipProperty.Comparator` is internal to the ORM's attribute mechanics. @@ -376,13 +378,30 @@ class RelationshipProperty(StrategizedProperty): def parententity(self): return self.property.parent - def __clause_element__(self): + def _source_selectable(self): elem = self.property.parent._with_polymorphic_selectable if self.adapter: return self.adapter(elem) else: return elem + def __clause_element__(self): + adapt_from = self._source_selectable() + if self._of_type: + of_type = inspect(self._of_type).mapper + else: + of_type = None + + pj, sj, source, dest, \ + secondary, target_adapter = self.property._create_joins( + source_selectable=adapt_from, + source_polymorphic=True, + of_type=of_type) + if sj is not None: + return pj & sj + else: + return pj + def of_type(self, cls): """Produce a construct that represents a particular 'subtype' of attribute for the parent class. @@ -477,7 +496,7 @@ class RelationshipProperty(StrategizedProperty): to_selectable = None if self.adapter: - source_selectable = self.__clause_element__() + source_selectable = self._source_selectable() else: source_selectable = None diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 750c3b298..2e38e0ce3 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -796,7 +796,7 @@ class _ORMJoin(expression.Join): prop = left_mapper.get_property(onclause) elif isinstance(onclause, attributes.QueryableAttribute): if adapt_from is None: - adapt_from = onclause.__clause_element__() + adapt_from = onclause.comparator._source_selectable() prop = onclause.property elif isinstance(onclause, MapperProperty): prop = onclause diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 63b1a4037..5b6e4d82d 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -4839,7 +4839,7 @@ class SelectBase(Executable, FromClause): return [self] -class ScalarSelect(Grouping): +class ScalarSelect(Generative, Grouping): _from_objects = [] def __init__(self, element): @@ -4853,13 +4853,17 @@ class ScalarSelect(Grouping): 'column-level expression.') c = columns + @_generative + def where(self, crit): + """Apply a WHERE clause to the SELECT statement referred to + by this :class:`.ScalarSelect`. + + """ + self.element = self.element.where(crit) + def self_group(self, **kwargs): return self - def _make_proxy(self, selectable, name=None, **kw): - return list(self.inner_columns)[0]._make_proxy( - selectable, name=name) - class CompoundSelect(SelectBase): """Forms the basis of ``UNION``, ``UNION ALL``, and other SELECT-based set operations.""" |
