gpt4 book ai didi

python - 如何在 SQLAlchemy 中使用空集合进行分页查询?

转载 作者:太空宇宙 更新时间:2023-11-04 06:19:10 25 4
gpt4 key购买 nike

我正在尝试寻找一种节省内存的方法来执行分页查询以测试空集合,但似乎无法弄清楚如何在大型数据库上有效地执行此操作。表格布局使用具有双向反向引用的关联对象。它与 documentation 非常相似.

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)

如果删除成员(member),会级联删除该成员(member)的关联。但是, block 对象将在数据库中被孤立。要删除孤立 block ,我可以使用如下查询测试空集合:

session.query(Chunk).filter(~Chunk.assoc.any())

然后删除 block :

query.delete(synchronize_session=False)

但是,如果关联表和 block 表很大,则查询或子查询似乎加载了所有内容并且内存激增。

我已经看到使用分页查询来限制标准查询的内存使用的概念 here :

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

然而,这似乎不适用于空集合查询,因为内存使用率仍然很高。有没有办法对这样的空集合进行分页查询?

最佳答案

我发现这里缺少一些东西。对空 block 的查询似乎基本没问题。我看到的内存使用率峰值来自代码中几行前的查询,当时实际成员本身已被删除。

member = session.query(Member).filter(Member.name == membername).one()
session.delete(member)

根据文档, session (默认情况下)只能删除加载到 session /内存中的对象。当成员被删除时,它将加载它的所有关联,以便根据级联规则删除它们。需要发生的是必须使用 passive deletes 绕过关联加载。 .

我补充说:

passive_deletes=True

Member类的关联关系和:

ondelete='CASCADE'

关联类的member_id 外键。我正在使用 SQLite3 并根据 docs 添加了引擎连接事件的外键支持.

关于孤立 block ,而不是使用 query.delete 方法批量删除 block 。我使用了一个不包含偏移量的页面查询,并在循环中从 session 中删除了 block ,如下所示。到目前为止,我似乎没有任何内存峰值:

def page_query(q):
while True:
r = False
for elem in q.limit(1000):
r = True
yield elem
if not r:
break

for chunk in page_query(query):
# Do something with the chunk if needed
session.delete(chunk)
session.commit()

长话短说,在删除具有大量集合的父对象时,使用 passive_deletes=True 似乎有很大帮助。页面查询在这种情况下似乎也能很好地工作,只是我必须取出偏移量,因为 block 正在从 session 内联中删除。

关于python - 如何在 SQLAlchemy 中使用空集合进行分页查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13598139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com