On Jul 27, 2010, at 12:03 PM, Jesse wrote:

> I'm having a problem when using correlate in a subquery.  I figured I
> would throw it in here before logging a bug report incase this is just
> user error.
> 
> I have two tables with a many-to-one relationship.  Estimate has a
> list of EstimateLines on it.  I want to select in the first
> EstimateLine that does not have a blank description to use as the
> description on Estimate.  When getting a list of Estimates I want to
> sort by the description.  Here is the code I'm using:
> 
> stmt = session.query(EstimateLine.description,
> EstimateLine.estimate_id)
> stmt = stmt.filter(EstimateLine.estimate_id == Estimate.id)
> stmt = stmt.correlate(Estimate)
> stmt = stmt.filter(EstimateLine.description != '')
> stmt = stmt.order_by(EstimateLine.lineno)
> stmt = stmt.limit(1)
> stmt = stmt.subquery()
> 
> query = session.query(Estimate.number, stmt.c.description)
> query = query.order_by(stmt.c.description)
> query.all()
> 
> Unfortunately the query it produces does not run.  It produces the
> following:
> SELECT estimates.number AS estimates_number, anon_1.description AS
> anon_1_description
> FROM estimates, (SELECT estimate_lines.description AS description,
> estimate_lines.estimate_id AS estimate_id
> FROM estimate_lines
> WHERE estimate_lines.estimate_id = estimates.id AND
> estimate_lines.description != ? ORDER BY estimate_lines.lineno
> LIMIT 1 OFFSET 0) AS anon_1 ORDER BY anon_1.description
> 
> Which gives an error of "no such column: estimates.id" (in SQLite).  I
> have a file for reproducing this.  What I would actually like is the
> subquery to be part of the SELECT statement and then order by it.
> Suggestions?

The SQL is actually exactly what you asked for.    SQLite doesn't like your 
attempt to join two selectables in the FROM clause using correlation, instead 
of a regular join of "Estimates" and "stmt".

Correlation implies you'd like your subquery in the columns or where clause.  
Such a subquery can only return exactly one row for one column, and in SQLA is 
referred to as a "scalar" selectable.   Call as_scalar() on your subquery, and 
use the resulting object as your column expression.  There is no .c. attribute.

That said, your subquery would be simpler and probably more efficient if you 
kept it in the FROM clause and simply joined them together without using 
correlation (query.filter(stmt.c.estimate_id==Estimate.id), remove the filter() 
from stmt).  As it stands, you will need to request your subquery once in the 
columns clause, implying that it is issued for every row (even though a decent 
query planner will realize that it can "unwrap" the correlation into a plain 
join), and then a second time in the ORDER BY clause, unless you give it a name 
(using label(), since an as_scalar() is a column expression), and then name the 
label in the order_by().





> 
> Thanks,
> 
> Jesse
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to