2013-02-12 72 views
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 

我想这样做是有一些不携带尽可能多klunky状态变量。如何清理这一点混乱的想法?

仅供参考 - 我已经试过这为好,不知道我喜欢它更好:

@staticmethod 
def qiter(q, start=0, batch=25000): 
    obj = True 
    while obj: 
     for obj in q.limit(batch).offset(start): 
      yield obj 
     start += batch 

回答

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

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

相关问题