在我的程序中,我需要读取一个非常大的表(它超过了内存存储)并自己编写以下构造来从表中读取并完成一些工作。虽然我知道将select重写为迭代器样式是非常可能的,但它仍然具有以下基本结构:
found = True
start = 0
batch = 2500
while found:
found = False
for obj in Channel.select().limit(batch).offset(start):
found = True
# do some big work...
start += batch
我想要做的是有些东西不会携带那些笨重的状态变量。关于如何清理这些混乱的想法?
仅供参考 - 我也试过这个,不确定我是否更喜欢它:
@staticmethod
def qiter(q, start=0, batch=25000):
obj = True
while obj:
for obj in q.limit(batch).offset(start):
yield obj
start += batch
答案 0 :(得分:1)
我找到的最短的内容如下:
for start in itertools.count(0, 2500):
objs = Channel.select().limit(2500).offset(start)
if not objs:
break
for obj in objs:
# do some big work...
基本上它是两件事的组合:
count
迭代器(来自标准库的itertools包)将批量计数减少到最小,并且break
语句来摆脱它。详细说明:
count
迭代器非常简单:它产生无限系列0,2500,5000,7500,....由于这个循环永远不会结束,我们需要在某个地方break
。这就是if语句发挥作用的地方。如果objs
是空列表,则break
存在外部循环。
答案 1 :(得分:0)
如果您只是迭代并且不想用完所有RAM,那么可以在QueryResultWrapper上查看“iterator()”方法。
例如,假设您需要迭代超过1,000,000行数据并将其序列化:
# let's assume we've got 1M stat objects to dump to csv
stats_qr = Stat.select().execute()
# our imaginary serializer class
serializer = CSVSerializer()
# loop over all the stats and serialize
for stat in stats_qr.iterator():
serializer.serialize_object(stat)
以下是文档的链接:
http://peewee.readthedocs.org/en/latest/peewee/cookbook.html#iterating-over-lots-of-rows