with_polymorphic(), or using from_self().
- sql
+ - An alias() of a select() will convert to a "scalar subquery"
+ when used in an unambiguously scalar context, i.e. it's used
+ in a comparison operation. This applies to
+ the ORM when using query.subquery() as well.
+
- Fixed missing _label attribute on Function object, others
when used in a select() with use_labels (such as when used
in an ORM column_property()). [ticket:1302]
return other.__clause_element__()
elif not isinstance(other, ClauseElement):
return self._bind_param(other)
- elif isinstance(other, _SelectBaseMixin):
+ elif isinstance(other, (_SelectBaseMixin, Alias)):
return other.as_scalar()
else:
return other
return Join(self, right, onclause, True)
def alias(self, name=None):
- """return an alias of this ``FromClause`` against another ``FromClause``."""
+ """return an alias of this ``FromClause``.
+
+ For table objects, this has the effect of the table being rendered
+ as ``tablename AS aliasname`` in a SELECT statement.
+ For select objects, the effect is that of creating a named
+ subquery, i.e. ``(select ...) AS aliasname``.
+ The ``alias()`` method is the general way to create
+ a "subquery" out of an existing SELECT.
+
+ The ``name`` parameter is optional, and if left blank an
+ "anonymous" name will be generated at compile time, guaranteed
+ to be unique against other anonymous constructs used in the
+ same statement.
+
+ """
return Alias(self, name)
def description(self):
return self.name.encode('ascii', 'backslashreplace')
+ def as_scalar(self):
+ try:
+ return self.element.as_scalar()
+ except AttributeError:
+ raise AttributeError("Element %s does not support 'as_scalar()'" % self.element)
+
def is_derived_from(self, fromclause):
if fromclause in self._cloned_set:
return True
l = list(session.query(User).instances(s.execute(emailad = 'jack@bean.com')))
eq_([User(id=7)], l)
-
+ def test_scalar_subquery(self):
+ 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())
+
+
def test_in(self):
session = create_session()
s = session.query(User.id).join(User.addresses).group_by(User.id).having(func.count(Address.id) > 2)
q2 = q.group_by([User.name.like('%j%')]).order_by(desc(User.name.like('%j%'))).values(User.name.like('%j%'), func.count(User.name.like('%j%')))
self.assertEquals(list(q2), [(True, 1), (False, 3)])
- def test_scalar_subquery(self):
+ def test_correlated_subquery(self):
"""test that a subquery constructed from ORM attributes doesn't leak out
those entities to the outermost query.
s = select([table1.c.myid]).correlate(None).as_scalar()
self.assert_compile(select([table1, s]), "SELECT mytable.myid, mytable.name, mytable.description, (SELECT mytable.myid FROM mytable) AS anon_1 FROM mytable")
+ # test that aliases use as_scalar() when used in an explicitly scalar context
+ s = select([table1.c.myid]).alias()
+ self.assert_compile(select([table1.c.myid]).where(table1.c.myid==s), "SELECT mytable.myid FROM mytable WHERE mytable.myid = (SELECT mytable.myid FROM mytable)")
+ self.assert_compile(select([table1.c.myid]).where(s > table1.c.myid), "SELECT mytable.myid FROM mytable WHERE mytable.myid < (SELECT mytable.myid FROM mytable)")
+
+
s = select([table1.c.myid]).as_scalar()
self.assert_compile(select([table2, s]), "SELECT myothertable.otherid, myothertable.othername, (SELECT mytable.myid FROM mytable) AS anon_1 FROM myothertable")