ページ化されたクエリを実行して空のコレクションをテストするためのメモリ効率の良い方法を見つけようとしていますが、大規模なデータベースで効率的に実行する方法がわかりません。テーブル レイアウトは、双方向の backref を持つ Association オブジェクトを使用します。ドキュメントと非常によく似ています。
class Association(Base):
__tablename__ = 'Association'
assoc_id = Column(Integer, primary_key=True, nullable=False, unique=True)
member_id = Column(Integer, ForeignKey('Member.id'))
chunk_id = Column(Integer, ForeignKey('Chunk.id'))
extra = Column(Text)
chunk = relationship("Chunk", backref=backref("assoc", lazy="dynamic"))
class Member(Base):
__tablename__ = 'Member'
id = Column(Integer, primary_key=True, nullable=False, unique=True)
assocs = relationship("Association", backref="member", cascade="all, delete", lazy="dynamic")
class Chunk(Base):
__tablename__ = 'Chunk'
id = Column(Integer, primary_key=True, nullable=False, unique=True)
name = Column(Text, unique=True)
メンバーが削除されると、メンバーの関連付けがカスケードされて削除されます。ただし、チャンク オブジェクトはデータベース内で孤立します。孤立したチャンクを削除するには、次のようなクエリを使用して空のコレクションをテストできます。
session.query(Chunk).filter(~Chunk.assoc.any())
次に、チャンクを次のように削除します。
query.delete(synchronize_session=False)
ただし、関連付けテーブルとチャンク テーブルが大きい場合、クエリまたはサブクエリがすべてをロードし、メモリが急上昇するようです。
ここで、ページ化されたクエリを使用して標準クエリのメモリ使用量を制限するという概念を見てきました。
def page_query(q, count=1000):
offset = 0
while True:
r = False
for elem in q.limit(count).offset(offset):
r = True
yield elem
offset += count
if not r:
break
for chunk in page_query(Session.query(Chunk)):
print chunk.name
ただし、メモリ使用量がまだ多いため、これは空のコレクション クエリでは機能しないようです。このような空のコレクションに対してページ クエリを実行する方法はありますか?