0

これを 1 つのクエリにマージして高速化することはできますか? テーブル Person と Cart があります (テーブルの ID は基本モデルから継承されます)

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))

これを1つのクエリに接着する方法は?

4

2 に答える 2

0

bpergo の回答に加えて、関係を築くことをお勧めします。簡単な解決策を示しますが、 Relationship Configurationを読むことを強くお勧めします。これは、すでに非常に優れたドキュメントの中で最も価値のあるドキュメントの 1 つです。

要するに: リレーションシップの考え方は、SQLAlchemy が必要なクエリを自動的に作成できるということです。

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

この変更により、これを非常に簡単に行うことができます。

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

ただし、注意が必要です。このソリューションだけでは、多数のクエリが発生する可能性があります (「リレーションシップの読み込みテクニック」を参照)。代わりにこれを行います。これにより、発行されるクエリがはるかに少なくなります。

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

いいえ、これは直接理解するのは簡単ではありません。しかし、リレーションシップを理解している場合、SQLAlchemy は本当に多くの作業を必要とするため、読む価値があることを保証します。

于 2013-08-26T17:53:26.107 に答える
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

于 2013-08-26T13:33:05.813 に答える