summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-04-23 11:50:47 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-04-23 11:50:47 -0400
commit8f35f7a803c67f4ab0620686592a021a24e4b331 (patch)
treec8245ecc0367a6ca6ab4bd7dfa68a99a2b952d9b
parentff0fb31bf205a82c4af8781ac9afc96586a67d66 (diff)
parent8b16cd876cb157d6f06863f2e345ff3e1d56972f (diff)
downloadsqlalchemy-8f35f7a803c67f4ab0620686592a021a24e4b331.tar.gz
- re-merge + CHANGES
-rw-r--r--AUTHORS1
-rw-r--r--CHANGES9
-rw-r--r--lib/sqlalchemy/orm/query.py2
-rw-r--r--lib/sqlalchemy/orm/strategies.py2
-rw-r--r--test/orm/test_froms.py82
5 files changed, 91 insertions, 5 deletions
diff --git a/AUTHORS b/AUTHORS
index a6ad7a7a8..ecc5d6cc7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -5,6 +5,7 @@ Major contributing authors include:
- Michael Bayer <mike_mp@zzzcomputing.com>
- Jason Kirtland <jek@discorporate.us>
- Gaetan de Menten <gdementen@gmail.com>
+- Diana Clarke <diana.joan.clarke@gmail.com>
- Michael Trier <mtrier@gmail.com>
- Philip Jenvey <pjenvey@underboss.org>
- Ants Aasma <ants.aasma@gmail.com>
diff --git a/CHANGES b/CHANGES
index 49e0dcea9..8fba962d4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -29,6 +29,15 @@ those which apply to an 0.7 release are noted.
approach can be upgraded to this new
approach. [ticket:1401]
+ - [feature] Query now "auto correlates" by
+ default in the same way as select() does.
+ Previously, a Query used as a subquery
+ in another would require the correlate()
+ method be called explicitly in order to
+ correlate a table on the inside to the
+ outside. As always, correlate(None)
+ disables correlation. [ticket:2179]
+
- [feature] Added prefix_with() method
to Query, calls upon select().prefix_with()
to allow placement of MySQL SELECT
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 924679085..b0ce9ee13 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -2907,7 +2907,6 @@ class Query(object):
context.whereclause,
from_obj=froms,
use_labels=labels,
- correlate=False,
# TODO: this order_by is only needed if
# LIMIT/OFFSET is present in self._select_args,
# else the application on the outside is enough
@@ -2973,7 +2972,6 @@ class Query(object):
from_obj=froms,
use_labels=labels,
for_update=for_update,
- correlate=False,
order_by=context.order_by,
**self._select_args
)
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 703fc0160..06b630076 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -749,7 +749,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
):
# reformat the original query
# to look only for significant columns
- q = orig_query._clone()
+ q = orig_query._clone().correlate(None)
# TODO: why does polymporphic etc. require hardcoding
# into _adapt_col_list ? Does query.add_columns(...) work
diff --git a/test/orm/test_froms.py b/test/orm/test_froms.py
index c8fc0af79..c41120bb9 100644
--- a/test/orm/test_froms.py
+++ b/test/orm/test_froms.py
@@ -66,6 +66,85 @@ class QueryTest(_fixtures.FixtureTest):
configure_mappers()
+class QueryCorrelatesLikeSelect(QueryTest, AssertsCompiledSQL):
+
+ query_correlated = "SELECT users.name AS users_name, " \
+ "(SELECT count(addresses.id) AS count_1 FROM addresses " \
+ "WHERE addresses.user_id = users.id) AS anon_1 FROM users"
+
+ query_not_correlated = "SELECT users.name AS users_name, " \
+ "(SELECT count(addresses.id) AS count_1 FROM addresses, users " \
+ "WHERE addresses.user_id = users.id) AS anon_1 FROM users"
+
+ def test_as_scalar_select_auto_correlate(self):
+ addresses, users = self.tables.addresses, self.tables.users
+ query = select(
+ [func.count(addresses.c.id)],
+ addresses.c.user_id==users.c.id
+ ).as_scalar()
+ query = select([users.c.name.label('users_name'), query])
+ self.assert_compile(query, self.query_correlated,
+ dialect=default.DefaultDialect()
+ )
+
+ def test_as_scalar_select_explicit_correlate(self):
+ addresses, users = self.tables.addresses, self.tables.users
+ query = select(
+ [func.count(addresses.c.id)],
+ addresses.c.user_id==users.c.id
+ ).correlate(users).as_scalar()
+ query = select([users.c.name.label('users_name'), query])
+ self.assert_compile(query, self.query_correlated,
+ dialect=default.DefaultDialect()
+ )
+
+ def test_as_scalar_select_correlate_off(self):
+ addresses, users = self.tables.addresses, self.tables.users
+ query = select(
+ [func.count(addresses.c.id)],
+ addresses.c.user_id==users.c.id
+ ).correlate(None).as_scalar()
+ query = select([ users.c.name.label('users_name'), query])
+ self.assert_compile(query, self.query_not_correlated,
+ dialect=default.DefaultDialect()
+ )
+
+ def test_as_scalar_query_auto_correlate(self):
+ sess = create_session()
+ Address, User = self.classes.Address, self.classes.User
+ query = sess.query(func.count(Address.id))\
+ .filter(Address.user_id==User.id)\
+ .as_scalar()
+ query = sess.query(User.name, query)
+ self.assert_compile(query, self.query_correlated,
+ dialect=default.DefaultDialect()
+ )
+
+ def test_as_scalar_query_explicit_correlate(self):
+ sess = create_session()
+ Address, User = self.classes.Address, self.classes.User
+ query = sess.query(func.count(Address.id))\
+ .filter(Address.user_id==User.id)\
+ .correlate(self.tables.users)\
+ .as_scalar()
+ query = sess.query(User.name, query)
+ self.assert_compile(query, self.query_correlated,
+ dialect=default.DefaultDialect()
+ )
+
+ def test_as_scalar_query_correlate_off(self):
+ sess = create_session()
+ Address, User = self.classes.Address, self.classes.User
+ query = sess.query(func.count(Address.id))\
+ .filter(Address.user_id==User.id)\
+ .correlate(None)\
+ .as_scalar()
+ query = sess.query(User.name, query)
+ self.assert_compile(query, self.query_not_correlated,
+ dialect=default.DefaultDialect()
+ )
+
+
class RawSelectTest(QueryTest, AssertsCompiledSQL):
"""compare a bunch of select() tests with the equivalent Query using straight table/columns.
@@ -90,10 +169,9 @@ class RawSelectTest(QueryTest, AssertsCompiledSQL):
)
# a little tedious here, adding labels to work around Query's auto-labelling.
- # also correlate needed explicitly. hmmm.....
# TODO: can we detect only one table in the "froms" and then turn off use_labels ?
s = sess.query(addresses.c.id.label('id'), addresses.c.email_address.label('email')).\
- filter(addresses.c.user_id==users.c.id).correlate(users).statement.alias()
+ filter(addresses.c.user_id==users.c.id).statement.alias()
self.assert_compile(sess.query(users, s.c.email).select_from(users.join(s, s.c.id==users.c.id)).with_labels().statement,
"SELECT users.id AS users_id, users.name AS users_name, anon_1.email AS anon_1_email "