From: Mike Bayer Date: Tue, 15 Jun 2010 00:07:44 +0000 (-0400) Subject: - Query.statement, Query.subquery(), etc. now transfer X-Git-Tag: rel_0_6_2~44 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a554d526745d6327e112460ea75f50d9ff2105f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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. --- diff --git a/CHANGES b/CHANGES index 94e4961c5c..53c90278ba 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 ae6624d473..50be13088e 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 5b5dd312d8..62602ff37b 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 ceb78ad1f1..d3c5c75f77 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 5b9a46d075..827630c3d0 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,\ @@ -42,6 +42,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)