being detached from any Session. UnboundExecutionError
is specific to engines bound to sessions and statements.
+ - Query called in the context of an expression will render
+ disambiguating labels in all cases. Note that this does
+ not apply to the existing .statement and .subquery()
+ accessor/method, which still honors the .with_labels()
+ setting that defaults to False.
+
+ - Query.union() retains disambiguating labels within the
+ returned statement, thus avoiding various SQL composition
+ errors which can result from column name conflicts.
+ [ticket:1676]
+
- sql
- Added math negation operator support, -x.
@property
def statement(self):
- """The full SELECT statement represented by this Query."""
+ """The full SELECT statement represented by this Query.
+
+ The statement by default will not have disambiguating labels
+ applied to the construct unless with_labels(True) is called
+ first.
+
+ """
return self._compile_context(labels=self._with_labels).\
statement._annotate({'_halt_adapt': True})
Eager JOIN generation within the query is disabled.
+ The statement by default will not have disambiguating labels
+ applied to the construct unless with_labels(True) is called
+ first.
+
"""
return self.enable_eagerloads(False).statement.alias()
def __clause_element__(self):
- return self.enable_eagerloads(False).statement
+ return self.enable_eagerloads(False).with_labels().statement
@_generative()
def enable_eagerloads(self, value):
# this is actually not legal on most DBs since the subquery has no alias
q1 = s.query(User).filter(User.name=='ed')
+
+
self.assert_compile(
select([q1]),
- "SELECT id, name FROM (SELECT users.id AS id, users.name AS name FROM users WHERE users.name = :name_1)",
+ "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()
)
[User(name='ed'), User(name='fred'), User(name='jack')]
)
+ def test_statement_labels(self):
+ """test that label conflicts don't occur with joins etc."""
+
+ s = create_session()
+ q1 = s.query(User, Address).join(User.addresses).\
+ filter(Address.email_address=="ed@wood.com")
+ q2 = s.query(User, Address).join(User.addresses).\
+ filter(Address.email_address=="jack@bean.com")
+ q3 = q1.union(q2).order_by(User.name)
+
+ eq_(
+ q3.all(),
+ [
+ (User(name='ed'), Address(email_address="ed@wood.com")),
+ (User(name='jack'), Address(email_address="jack@bean.com")),
+ ]
+ )
+
def test_union_labels(self):
- """test that column expressions translate during the _from_statement() portion of union(), others"""
+ """test that column expressions translate during
+ the _from_statement() portion of union(), others"""
s = create_session()
q1 = s.query(User, literal("x"))
self.assert_compile(
q3,
- "SELECT anon_1.id AS anon_1_id, anon_1.name AS anon_1_name, anon_1.anon_2 AS anon_1_anon_2 FROM "
- "(SELECT users.id AS id, users.name AS name, :param_1 AS anon_2 FROM users "
- "UNION SELECT users.id AS id, users.name AS name, 'y' FROM users) AS anon_1"
+ "SELECT anon_1.users_id AS anon_1_users_id, anon_1.users_name AS anon_1_users_name,"
+ " anon_1.anon_2 AS anon_1_anon_2 FROM (SELECT users.id AS users_id, users.name AS"
+ " users_name, :param_1 AS anon_2 FROM users UNION SELECT users.id AS users_id, "
+ "users.name AS users_name, 'y' FROM users) AS anon_1"
, use_default_dialect = True
)