summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/selectresults.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2006-09-27 07:08:26 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2006-09-27 07:08:26 +0000
commita81bd92d6ebef5053cbb6882b336c50c1134c273 (patch)
tree6d9df595eedaa29794e7a02122f79cc3cf73b1c9 /lib/sqlalchemy/ext/selectresults.py
parentdf9c1a10b568cb89aec41fcb0c7c31a1ae75943c (diff)
downloadsqlalchemy-a81bd92d6ebef5053cbb6882b336c50c1134c273.tar.gz
- specifying joins in the from_obj argument of query.select() will
replace the main table of the query, if the table is somewhere within the given from_obj. this makes it possible to produce custom joins and outerjoins in queries without the main table getting added twice. [ticket:315] - added join_to and outerjoin_to transformative methods to SelectResults, to build up join/outerjoin conditions based on property names. also added select_from to explicitly set from_obj parameter. - factored "results" arrays from the mapper test suite and into the "tables" mapper - added "viewonly" param to docs
Diffstat (limited to 'lib/sqlalchemy/ext/selectresults.py')
-rw-r--r--lib/sqlalchemy/ext/selectresults.py66
1 files changed, 60 insertions, 6 deletions
diff --git a/lib/sqlalchemy/ext/selectresults.py b/lib/sqlalchemy/ext/selectresults.py
index a35cdfa7e..93698a5e0 100644
--- a/lib/sqlalchemy/ext/selectresults.py
+++ b/lib/sqlalchemy/ext/selectresults.py
@@ -18,13 +18,14 @@ class SelectResults(object):
instance with further limiting criterion added. When interpreted
in an iterator context (such as via calling list(selectresults)), executes the query."""
- def __init__(self, query, clause=None, ops={}):
+ def __init__(self, query, clause=None, ops={}, joinpoint=None):
"""constructs a new SelectResults using the given Query object and optional WHERE
clause. ops is an optional dictionary of bind parameter values."""
self._query = query
self._clause = clause
self._ops = {}
self._ops.update(ops)
+ self._joinpoint = joinpoint or (self._query.table, self._query.mapper)
def count(self):
"""executes the SQL count() function against the SelectResults criterion."""
@@ -60,7 +61,7 @@ class SelectResults(object):
def clone(self):
"""creates a copy of this SelectResults."""
- return SelectResults(self._query, self._clause, self._ops.copy())
+ return SelectResults(self._query, self._clause, self._ops.copy(), self._joinpoint)
def filter(self, clause):
"""applies an additional WHERE clause against the query."""
@@ -68,23 +69,76 @@ class SelectResults(object):
new._clause = sql.and_(self._clause, clause)
return new
+ def select(self, clause):
+ return self.filter(clause)
+
def order_by(self, order_by):
- """applies an ORDER BY to the query."""
+ """apply an ORDER BY to the query."""
new = self.clone()
new._ops['order_by'] = order_by
return new
def limit(self, limit):
- """applies a LIMIT to the query."""
+ """apply a LIMIT to the query."""
return self[:limit]
def offset(self, offset):
- """applies an OFFSET to the query."""
+ """apply an OFFSET to the query."""
return self[offset:]
def list(self):
- """returns the results represented by this SelectResults as a list. this results in an execution of the underlying query."""
+ """return the results represented by this SelectResults as a list.
+
+ this results in an execution of the underlying query."""
return list(self)
+
+ def select_from(self, from_obj):
+ """set the from_obj parameter of the query to a specific table or set of tables.
+
+ from_obj is a list."""
+ new = self.clone()
+ new._ops['from_obj'] = from_obj
+ return new
+
+ def join_to(self, prop):
+ """join the table of this SelectResults to the table located against the given property name.
+
+ subsequent calls to join_to or outerjoin_to will join against the rightmost table located from the
+ previous join_to or outerjoin_to call, searching for the property starting with the rightmost mapper
+ last located."""
+ new = self.clone()
+ (clause, mapper) = self._join_to(prop, outerjoin=False)
+ new._ops['from_obj'] = [clause]
+ new._joinpoint = (clause, mapper)
+ return new
+
+ def outerjoin_to(self, prop):
+ """outer join the table of this SelectResults to the table located against the given property name.
+
+ subsequent calls to join_to or outerjoin_to will join against the rightmost table located from the
+ previous join_to or outerjoin_to call, searching for the property starting with the rightmost mapper
+ last located."""
+ new = self.clone()
+ (clause, mapper) = self._join_to(prop, outerjoin=True)
+ new._ops['from_obj'] = [clause]
+ new._joinpoint = (clause, mapper)
+ return new
+
+ def _join_to(self, prop, outerjoin=False):
+ [keys,p] = self._query._locate_prop(prop, start=self._joinpoint[1])
+ clause = self._joinpoint[0]
+ mapper = self._joinpoint[1]
+ for key in keys:
+ prop = mapper.props[key]
+ if outerjoin:
+ clause = clause.outerjoin(prop.mapper.mapped_table, prop.get_join())
+ else:
+ clause = clause.join(prop.mapper.mapped_table, prop.get_join())
+ mapper = prop.mapper
+ return (clause, mapper)
+
+ def compile(self):
+ return self._query.compile(self._clause, **self._ops)
def __getitem__(self, item):
if isinstance(item, slice):