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

标签 python sqlalchemy

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

相关文章:

python - 用棉花糖序列化日期时间的简短方法

python - Flask-Sqlalchemy 貌似 "caching"查询

python - 从 Python 到 Html 的解析时间

python - flask 棉花糖 JSON 字段

python - sqlalchemy中查询相关表

python - 如何让 SQLAlchemy 正确地将 unicode 省略号插入到 mySQL 表中?

应用程序启动时进行Python数据库迁移

python - matplotlib.pyplot.hist 返回一个直方图,当我有不同的数据时,所有 bin 都具有相同的值

python - 如何将内容处置 header 设置为文件部分的附件?

python - 如何将 pandas DataFrame 的列转换为列表列表?