[Sqlalchemy-commits] sqlalchemy: - Fixed bug whereby comparison of column
Brought to you by:
zzzeek
From: <co...@sq...> - 2011-06-13 00:35:53
|
details: http://hg.sqlalchemy.org/sqlalchemy/sqlalchemy/rev/de5c48a47cdc changeset: 7675:de5c48a47cdc user: zzzeek date: Sun Jun 12 20:35:37 2011 -0400 description: - Fixed bug whereby comparison of column expression to a Query() would not call as_scalar() on the underlying SELECT statement to produce a scalar subquery, in the way that occurs if you called it on Query().subquery(). [ticket:2190] - some cleanup to test.orm.test_query diffstat: CHANGES | 7 +++ lib/sqlalchemy/sql/expression.py | 5 ++- test/orm/test_query.py | 80 ++++++++++++++++++++++------------------ 3 files changed, 55 insertions(+), 37 deletions(-) diffs (279 lines): diff -r f9faaf09e7b7 -r de5c48a47cdc CHANGES --- a/CHANGES Wed Jun 08 17:56:00 2011 -0400 +++ b/CHANGES Sun Jun 12 20:35:37 2011 -0400 @@ -11,6 +11,13 @@ relationship.order_by, foreign_keys, remote_side, etc. + - Fixed bug whereby comparison of column + expression to a Query() would not call + as_scalar() on the underlying SELECT + statement to produce a scalar subquery, + in the way that occurs if you called + it on Query().subquery(). [ticket:2190] + - mssql - Adjusted the pyodbc dialect such that bound values are passed as bytes and not unicode diff -r f9faaf09e7b7 -r de5c48a47cdc lib/sqlalchemy/sql/expression.py --- a/lib/sqlalchemy/sql/expression.py Wed Jun 08 17:56:00 2011 -0400 +++ b/lib/sqlalchemy/sql/expression.py Sun Jun 12 20:35:37 2011 -0400 @@ -1943,7 +1943,10 @@ other.type = self.type return other elif hasattr(other, '__clause_element__'): - return other.__clause_element__() + other = other.__clause_element__() + if isinstance(other, (_SelectBase, Alias)): + other = other.as_scalar() + return other elif not isinstance(other, ClauseElement): return self._bind_param(operator, other) elif isinstance(other, (_SelectBase, Alias)): diff -r f9faaf09e7b7 -r de5c48a47cdc test/orm/test_query.py --- a/test/orm/test_query.py Wed Jun 08 17:56:00 2011 -0400 +++ b/test/orm/test_query.py Sun Jun 12 20:35:37 2011 -0400 @@ -1,19 +1,22 @@ from test.lib.testing import eq_, assert_raises, assert_raises_message import operator -from sqlalchemy import * +from sqlalchemy import MetaData, null, exists, text, union, literal, \ + literal_column, func, between, Unicode, desc, and_, bindparam, \ + select, distinct from sqlalchemy import exc as sa_exc, util from sqlalchemy.sql import compiler, table, column +from sqlalchemy.sql import expression from sqlalchemy.engine import default -from sqlalchemy.orm import * -from sqlalchemy.orm import attributes +from sqlalchemy.orm import attributes, mapper, relationship, backref, \ + configure_mappers, create_session, synonym, Session, class_mapper, \ + aliased, column_property, joinedload_all, joinedload, Query from test.lib.assertsql import CompiledSQL from test.lib.testing import eq_ +from test.lib.schema import Table, Column import sqlalchemy as sa -from test.lib import testing, AssertsCompiledSQL, Column, engines - +from test.lib import testing, AssertsCompiledSQL, engines from test.orm import _fixtures - from test.lib import fixtures from sqlalchemy.orm.util import join, outerjoin, with_parent @@ -731,6 +734,7 @@ class ExpressionTest(QueryTest, AssertsCompiledSQL): + __dialect__ = 'default' def test_deferred_instances(self): User, addresses, Address = (self.classes.User, @@ -757,20 +761,27 @@ "addresses.id AS addresses_id, addresses.user_id AS " "addresses_user_id, addresses.email_address AS " "addresses_email_address FROM users JOIN addresses " - "ON users.id = addresses.user_id) AS anon_1", - use_default_dialect=True + "ON users.id = addresses.user_id) AS anon_1" ) - def test_scalar_subquery(self): + def test_scalar_subquery_compile_whereclause(self): User = self.classes.User + Address = self.classes.Address session = create_session() - q = session.query(User.id).filter(User.id==7).subquery() - - q = session.query(User).filter(User.id==q) - - eq_(User(id=7), q.one()) + q = session.query(User.id).filter(User.id==7) + + q = session.query(Address).filter(Address.user_id==q) + assert isinstance(q._criterion.right, expression.ColumnElement) + self.assert_compile( + q, + "SELECT addresses.id AS addresses_id, addresses.user_id " + "AS addresses_user_id, addresses.email_address AS " + "addresses_email_address FROM addresses WHERE " + "addresses.user_id = (SELECT users.id AS users_id " + "FROM users WHERE users.id = :id_1)" + ) def test_named_subquery(self): User = self.classes.User @@ -793,8 +804,7 @@ q = session.query(User.id).filter(User.id==7).label('foo') self.assert_compile( session.query(q), - "SELECT (SELECT users.id FROM users WHERE users.id = :id_1) AS foo", - use_default_dialect=True + "SELECT (SELECT users.id FROM users WHERE users.id = :id_1) AS foo" ) def test_as_scalar(self): @@ -808,8 +818,7 @@ 'SELECT users.id AS users_id, users.name ' 'AS users_name FROM users WHERE users.id ' 'IN (SELECT users.id FROM users WHERE ' - 'users.id = :id_1)', - use_default_dialect=True) + 'users.id = :id_1)') def test_param_transfer(self): @@ -857,8 +866,7 @@ self.assert_compile( select([q1]), "SELECT users_id, users_name FROM (SELECT users.id AS users_id, " - "users.name AS users_name FROM users WHERE users.name = :name_1)", - dialect=default.DefaultDialect() + "users.name AS users_name FROM users WHERE users.name = :name_1)" ) def test_join(self): @@ -2278,7 +2286,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Keyword], - (eagerload(Item.keywords), ), + (joinedload(Item.keywords), ), r"Can't find property 'keywords' on any entity specified " r"in this Query. Note the full path from root " r"\(Mapper\|Keyword\|keywords\) to target entity must be specified." @@ -2288,7 +2296,7 @@ Item = self.classes.Item self._assert_eager_not_found_exception( [Item], - (eagerload("foo"), ), + (joinedload("foo"), ), r"Can't find property named 'foo' on the mapped " r"entity Mapper\|Item\|items in this Query." ) @@ -2297,7 +2305,7 @@ Item = self.classes.Item self._assert_eager_not_found_exception( [Item], - (eagerload("keywords.foo"), ), + (joinedload("keywords.foo"), ), r"Can't find property named 'foo' on the mapped entity " r"Mapper\|Keyword\|keywords in this Query." ) @@ -2306,7 +2314,7 @@ Item = self.classes.Item self._assert_eager_not_found_exception( [Item], - (eagerload_all("keywords.foo"), ), + (joinedload_all("keywords.foo"), ), r"Can't find property named 'foo' on the mapped entity " r"Mapper\|Keyword\|keywords in this Query." ) @@ -2318,7 +2326,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Keyword, Item], - (eagerload_all("keywords"), ), + (joinedload_all("keywords"), ), r"Attribute 'keywords' of entity 'Mapper\|Keyword\|keywords' " "does not refer to a mapped entity" ) @@ -2330,7 +2338,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Keyword, Item], - (eagerload_all("keywords"), ), + (joinedload_all("keywords"), ), r"Attribute 'keywords' of entity 'Mapper\|Keyword\|keywords' " "does not refer to a mapped entity" ) @@ -2339,7 +2347,7 @@ Item = self.classes.Item self._assert_eager_not_found_exception( [Item], - (eagerload_all("id", "keywords"), ), + (joinedload_all("id", "keywords"), ), r"Attribute 'id' of entity 'Mapper\|Item\|items' does not " r"refer to a mapped entity" ) @@ -2349,7 +2357,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Keyword, Item], - (eagerload_all("id", "keywords"), ), + (joinedload_all("id", "keywords"), ), r"Attribute 'id' of entity 'Mapper\|Keyword\|keywords' " "does not refer to a mapped entity" ) @@ -2359,7 +2367,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Keyword, Item], - (eagerload_all("description"), ), + (joinedload_all("description"), ), r"Can't find property named 'description' on the mapped " r"entity Mapper\|Keyword\|keywords in this Query." ) @@ -2369,7 +2377,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Keyword.id, Item.id], - (eagerload_all("keywords"), ), + (joinedload_all("keywords"), ), r"Query has only expression-based entities - can't find property " "named 'keywords'." ) @@ -2379,7 +2387,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Keyword, Item], - (eagerload_all(Keyword.id, Item.keywords), ), + (joinedload_all(Keyword.id, Item.keywords), ), r"Attribute 'Keyword.id' of entity 'Mapper\|Keyword\|keywords' " "does not refer to a mapped entity" ) @@ -2389,7 +2397,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Keyword, Item], - (eagerload_all(Keyword.keywords, Item.keywords), ), + (joinedload_all(Keyword.keywords, Item.keywords), ), r"Attribute 'Keyword.keywords' of entity 'Mapper\|Keyword\|keywords' " "does not refer to a mapped entity" ) @@ -2399,7 +2407,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Keyword.id, Item.id], - (eagerload_all(Keyword.keywords, Item.keywords), ), + (joinedload_all(Keyword.keywords, Item.keywords), ), r"Query has only expression-based entities - " "can't find property named 'keywords'." ) @@ -2409,7 +2417,7 @@ Keyword = self.classes.Keyword self._assert_eager_not_found_exception( [Item], - (eagerload_all(Keyword), ), + (joinedload_all(Keyword), ), r"mapper option expects string key or list of attributes" ) @@ -2431,7 +2439,7 @@ Item = self.classes.Item q = create_session().query(*entity_list).\ - options(eagerload(option)) + options(joinedload(option)) key = ('loaderstrategy', (class_mapper(Item), 'keywords')) assert key in q._attributes @@ -2446,4 +2454,4 @@ eager_option, message): assert_raises_message(sa.exc.ArgumentError, message, create_session().query(column).options, - eagerload(eager_option)) + joinedload(eager_option)) |