SQLalchemy每个类别的前3个结果

时间:2014-12-15 05:43:32

标签: python sqlalchemy

我有一个模特:

class Contract(ContractJsonSerializer, db.Model):
    __tablename__ = 'contracts'

    id = db.Column(db.Unicode(32), primary_key=True)
    device_name = db.Column(db.Unicode(256), nullable=False)
    monthly_price = db.Column(db.Numeric(precision=6, scale=2))
    network_id = db.Column(db.Integer(), db.ForeignKey('networks.id'))

class Network(NetworkJsonSerializer, db.Model):
    __tablename__ = 'networks'

    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.Unicode(20), nullable=False)
    contracts = db.relationship('Contract', backref='network')

如何从每个网络获得3个最便宜的合同?

我得到了以下SQL:

  set @num := 0, @network := '';

  select *
  from 
  (
     select *, 
        @num := if(@network = network_id, @num + 1, 1) as row_number,
        @network := network_id as dummy
    from contracts
    order by network_id, monthly_price
  ) as x 
  where x.row_number <= 3;

但是当我试图执行它时,我得到了:

contracts = Contract.query.from_statement(sql).all()

“ResourceClosedError:此结果对象不返回行。它已自动关闭。”

我可以用声明的方式来做吗?如果不是解决这个问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

经过几个小时的google&amp; sqlalchemy docs我有这个:

# create query order by monthly price 
base_query = Contract.query.order_by(Contract.monthly_price)

# build subqueries for each network 
queries = []
for n in networks.all():
    queries.append( base_query.filter(Contract.network_id==n.id).\
                        limit(3).subquery().select() )

# get contracts using union_all
contracts = Contract.query.select_entity_from(union_all( *queries )).all()

它似乎工作正常 - 在一个查询中为每个网络返回3个最便宜的合同。