summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-06-14 20:07:44 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2010-06-14 20:07:44 -0400
commit7a554d526745d6327e112460ea75f50d9ff2105f (patch)
tree54866c6b966dd0c7d9d65bcad08f0571fb28daa7
parent33f6dcc80b43e499562991d7bfaf4f896d55f445 (diff)
downloadsqlalchemy-7a554d526745d6327e112460ea75f50d9ff2105f.tar.gz
- Query.statement, Query.subquery(), etc. now transfer
the values of bind parameters, i.e. those specified by query.params(), into the resulting SQL expression. Previously the values would not be transferred and bind parameters would come out as None. - Subquery-eager-loading now works with Query objects which include params(), as well as get() Queries.
-rw-r--r--CHANGES9
-rw-r--r--lib/sqlalchemy/orm/query.py7
-rw-r--r--lib/sqlalchemy/orm/strategies.py1
-rw-r--r--test/orm/test_query.py8
-rw-r--r--test/orm/test_subquery_relations.py41
5 files changed, 63 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index 94e4961c5..53c90278b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,15 @@ CHANGES
in one flush would fail to insert a row for both
sides. Regression from 0.5. [ticket:1824]
+ - Query.statement, Query.subquery(), etc. now transfer
+ the values of bind parameters, i.e. those specified
+ by query.params(), into the resulting SQL expression.
+ Previously the values would not be transferred
+ and bind parameters would come out as None.
+
+ - Subquery-eager-loading now works with Query objects
+ which include params(), as well as get() Queries.
+
- sql
- The warning emitted by the Unicode and String types
with convert_unicode=True no longer embeds the actual
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index ae6624d47..50be13088 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -399,8 +399,11 @@ class Query(object):
"""
- return self._compile_context(labels=self._with_labels).\
- statement._annotate({'_halt_adapt': True})
+ stmt = self._compile_context(labels=self._with_labels).\
+ statement
+ if self._params:
+ stmt = stmt.params(self._params)
+ return stmt._annotate({'_halt_adapt': True})
def subquery(self):
"""return the full SELECT statement represented by this Query,
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 5b5dd312d..62602ff37 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -700,6 +700,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
# reformat the original query
# to look only for significant columns
q = orig_query._clone()
+
# TODO: why does polymporphic etc. require hardcoding
# into _adapt_col_list ? Does query.add_columns(...) work
# with polymorphic loading ?
diff --git a/test/orm/test_query.py b/test/orm/test_query.py
index ceb78ad1f..d3c5c75f7 100644
--- a/test/orm/test_query.py
+++ b/test/orm/test_query.py
@@ -584,6 +584,14 @@ class ExpressionTest(QueryTest, AssertsCompiledSQL):
eq_(User(id=7), q.one())
+ def test_param_transfer(self):
+ session = create_session()
+
+ q = session.query(User.id).filter(User.id==bindparam('foo')).params(foo=7).subquery()
+
+ q = session.query(User).filter(User.id==q)
+
+ eq_(User(id=7), q.one())
def test_in(self):
session = create_session()
diff --git a/test/orm/test_subquery_relations.py b/test/orm/test_subquery_relations.py
index 5b9a46d07..827630c3d 100644
--- a/test/orm/test_subquery_relations.py
+++ b/test/orm/test_subquery_relations.py
@@ -1,7 +1,7 @@
from sqlalchemy.test.testing import eq_, is_, is_not_
from sqlalchemy.test import testing
from sqlalchemy.test.schema import Table, Column
-from sqlalchemy import Integer, String, ForeignKey
+from sqlalchemy import Integer, String, ForeignKey, bindparam
from sqlalchemy.orm import backref, subqueryload, subqueryload_all, \
mapper, relationship, clear_mappers,\
create_session, lazyload, aliased, joinedload,\
@@ -43,6 +43,45 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
self.assert_sql_count(testing.db, go, 2)
@testing.resolve_artifact_names
+ def test_from_get(self):
+ mapper(User, users, properties={
+ 'addresses':relationship(
+ mapper(Address, addresses),
+ order_by=Address.id)
+ })
+ sess = create_session()
+
+ q = sess.query(User).options(subqueryload(User.addresses))
+ def go():
+ eq_(
+ User(id=7, addresses=[
+ Address(id=1, email_address='jack@bean.com')]),
+ q.get(7)
+ )
+
+ self.assert_sql_count(testing.db, go, 2)
+
+ @testing.resolve_artifact_names
+ def test_from_params(self):
+ mapper(User, users, properties={
+ 'addresses':relationship(
+ mapper(Address, addresses),
+ order_by=Address.id)
+ })
+ sess = create_session()
+
+ q = sess.query(User).options(subqueryload(User.addresses))
+ def go():
+ eq_(
+ User(id=7, addresses=[
+ Address(id=1, email_address='jack@bean.com')]),
+ q.filter(User.id==bindparam('foo')).params(foo=7).one()
+ )
+
+ self.assert_sql_count(testing.db, go, 2)
+
+
+ @testing.resolve_artifact_names
def test_many_to_many(self):
mapper(Keyword, keywords)
mapper(Item, items, properties = dict(