2011-09-23 53 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