如何将嵌套for循环中的两个查询粘合在一起?

时间:2013-08-26 13:29:30

标签: python python-2.7 sqlalchemy

我可以将此合并到一个查询中并使其更快 我有表Person和Cart(表中的id继承自Base模型)

class PersonModel(Base):
    __tablename__ = 'persons'
    username = Column(String(30), nullable=True, default=None)
    email = Column(String(75), nullable=True, default=None)
    password = Column(String(128), nullable=True, default=None)

class CartModel(Base):
    __tablename__ = 'carts'
    person_id = Column(Integer, ForeignKey('persons.id'), nullable=False, index=True)
    text = Column(String(300), nullable=True)
    began_at = Column(BigInteger, nullable=False)
    ended_at = Column(BigInteger, nullable=False, default=utc_time)
    datetime = Column(TIMESTAMP, server_default=func.now())
    money = Column(Float, default=0)
    quantity = Column(Integer, default=0)

我需要查找从时间t开始发生的所有购物车的人员和购物车数量的用户名。

result = []
for c in session.query(CartModel).filter(CartMode.ended_at >= t).all():
    p = session.query(PersonModel).filter(PersonModel.id == c.person_id).first()
    if p:
      result.append((p.username, c.quantity))

如何将此粘贴到一个查询?

2 个答案:

答案 0 :(得分:0)

session.query(CartModel).join(CartModel.person_id).filter(CartMode.ended_at >= t).all()

请参阅文档中的此部分:http://docs.sqlalchemy.org/en/latest/core/tutorial.html#using-joins

答案 1 :(得分:0)

除了bpergo的回答,我建议你建立一种关系。我给你一个快速解决方案,但我强烈建议你阅读Relationship Configuration。这是关于已经非常好的文档的最有价值的文档之一。

简而言之:关系的想法是SQLAlchemy可以自动构建您需要的查询:

class PersonModel(Base):
    ...
    carts = relationship("CartModel", backref="person")

通过此修改,您可以非常轻松地执行此操作:

for c in session.query(CartModel).filter(CartMode.ended_at >= t):
    p = c.person
    ...

但是,您必须注意:只有这个解决方案,您最终可能会遇到大量查询(请参阅:Relationship Loading Techniques)。而是这样做,它将发出更少的查询:

for c in session.query(CartModel).option(joinedload(PersonModel)).filter(CartModel.ended_at >= t):
    p = c.person
    ...

不,我确信这不容易理解。但我向你保证,值得一读的是,如果你理解了人际关系,那么SQLAlchemy可以真正地接受你手中的很多的工作。