逐个从数据库中获取结果

时间:2013-04-11 12:02:50

标签: python database sqlalchemy

我正在编写一个查询数据库结果的小程序(单表)。我正在使用python 3.3,sqlalchemy和postgres数据库。

result = db_session.query(Data).all()
progress = 0
for row in result:
    update_progress_bar(progress, len(result))
    do_something_with_data(row)
    progress += 1

变量'result'将包含数千行,并且数据处理需要一些时间。这就是为什么我介绍了简单的进度条来了解它将花费多少时间。 问题是,总时间的30%是对数据库进行排队(第一行)。因此,当我开始计划时,我的进度条开始移动之前会有很大的延迟。另外,我不需要将所有结果保存在内存中。我可以单独处理它们。

有没有办法修改上面的程序来逐行获取行,直到收到所有行,而不将所有内容都加载到内存中?另外,我想监视查询和处理数据的进度。

1 个答案:

答案 0 :(得分:3)

您只需循环查询,无需调用.all()调用.yield_per()来设置批量大小:

for row in db_session.query(Data).yield_per(10):
    do_something_with_data(row)

.all()确实将整个结果集转换为 first 列表,如果结果集很大则会导致延迟。设置.yield_per()后直接迭代查询而不是根据需要获取结果,提供数据库API支持

如果您想预先知道将返回多少行,请先致电.count()

result = db_session.query(Data)
count = result.count()

for row in result.yield_per(10):
    update_progress_bar(progress, count)
    do_something_with_data(row)
    progress += 1

.count()要求数据库首先为我们提供项目计数。

您的数据库仍然预先缓存结果行,导致启动延迟,即使使用.yield_per()也是如此。在这种情况下,您需要使用windowed query根据列中一个中的值范围将查询分解为块。这是否有效取决于您的确切表格布局。