Python SQLalchemy每个类别的前3名结果

Python SQLalchemy每个类别的前3名结果,python,sqlalchemy,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(prec

我有一个模型:

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;
“ResourceClosedError:此结果对象不返回行。它已自动关闭。”


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

在谷歌和sqlalchemy文档发布几个小时后,我得到了以下信息:

# 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个最便宜的合同。

您使用哪个数据库?
# 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()