2011-09-23 51 views
2

我以this爲例來幫助我學習sqlalchemy。下面是MySQL數據庫:如何在sqlalchemy中表示此查詢?

select f.type, f.variety, f.price 
from (
    select type, min(price) as minprice 
    from fruits group by type 
) as x inner join fruits as f on f.type = x.type and f.price = x.minprice; 

這是我到目前爲止有:

s = Session() 
sq = s.query(func.min(fruit.price)).group_by(fruit.type).subquery() 
ans = s.query(fruit).join(sq, fruit.price==sq.c.price).all() 

,但它顯然是行不通的。我甚至關閉?

我一直在傾注這些docsprice是一個PK,如果有幫助..也許我需要一個別名或別的東西。任何幫助或方向表示讚賞。

回答

1

SOLUTION:下面應該這樣做:

版本時fruitTable實例:

q = (select([fruit.type, func.min(fruit.price).label("min_price")]). 
    group_by(fruit.type)).alias("subq") 
s = (session.query(fruit). 
     join(q, and_(fruit.type==q.c.type, fruit.price == q.c.min_price)) 
    ) 
res = s.all() 

邊注:當fruitModel

q = (select([fruit.c.type, func.min(fruit.c.price).label("min_price")]). 
    group_by(fruit.c.type)).alias("subq") 

s = select([fruit], 
      and_(fruit.c.type == q.c.type, 
       fruit.c.price == q.c.min_price) 
    ) 
res = session.execute(s) 

版本:浮動列作爲一個PK聽起來不是一個好主意......而且真的,不能兩種不同的水果有相同的價格(這將違反唯一性)?

+0

謝謝。多謝。我得到一個「水果沒有屬性c」的錯誤,所以我認爲你的意思是'fruit.type',而不是'fruit.c.type'等。如果不是,我想知道你的SA版本是什麼正在使用。 (關於附註,你是絕對正確的,我打算把我在這裏學到的東西應用到一個更復雜的查詢中,該查詢選擇了最大的'fruit.id',這確實是一個int和PK。) – Paul

+0

我認爲在我的例子中'fruit'是一個'Table',而在你的例子中它可能是一個模型類。從你的模型類中,你可以通過做'fruit.__ table__'來獲得一個表格。 – van

+0

@van:從模型類獲取表格只適用於聲明模型;公共接口是'sqlalchemy.orm.attributes.manager_of_class(MAPPED_CLASS).mapper.mapped_table',它可以在任何映射類上工作,不管它們是如何定義的。 – SingleNegationElimination

1

我不能確定這是因爲我不知道你得到了什麼異常。

既然你試圖讓SQLAlchemy的執行類似的查詢您發佈的一個,在你有你的from子句select聲明,你就需要調用mapper上類似於sqlalchemy.select的結果鏈接的例子。這個映射的類將是您試圖模擬的查詢中的x。然後你可以做session.query(fruits).join((x, ...)).filter(...以得到最終結果。

相比之下,查詢對象的subquery方法適用於需要a select statement in the where clause的情況,如where column in (select ...)。使用subquery獲取將在最終生成的查詢中選擇的內容內部。然後,您可以創建一個單獨的(外部)查詢並加入subquery調用的結果。爲了讓SQLAlchemy使用類似於你的例子的查詢,它不會出現,你將需要使用這種技術。

+0

是否由於任何原因使用映射器優先於別名優先? – Paul

+0

對於你的例子的一個小例子,如果你的意思是使用'mapper'類而不是'Table',那麼可能沒有什麼好處。 – wberry

0

這也適用,是我最熟悉的語法。

s = Session() 
sq = s.query(func.min(fruit.price).label('min_price').\ 
     group_by(fruit.type).subquery() 
ans = s.query(fruit).join(sq, fruit.price==sq.c.min_price).all() 
+0

它假定價格是獨一無二的(你提到的是),但我不確定爲什麼蘋果在某個時間點不能和橘子一樣。我想說的是:如果多於一種類型的價格相同(最低),它將不起作用。 – van

+0

就像我在我的第一個評論在這裏所說:http://stackoverflow.com/questions/7534937/how-do-i-express-this-query-in-sqlalchemy/7552742#7552742價格是浮動在線示例。在我的現實世界中,他們是主要的ID – Paul