2013-02-12 61 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

相關問題