2

在我的程序中,我需要读取一个非常大的表(它超出了内存存储)并让我自己编写以下构造来从表中读取并做一些工作。虽然我知道很有可能将选择重写为迭代器样式,但它仍然具有以下基本结构:

    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
4

2 回答 2

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存在外循环。

于 2013-02-12T21:17:52.753 回答
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

于 2013-02-18T03:26:46.330 回答