2014-07-02 22 views
3

我想編寫一個生成器函數,該函數將在內存有限的系統上運行,該系統使用PyMySql(或MySQLDb)一次返回一個選擇查詢的結果。下面的作品:在內存有效的生成器中使用PyMySql的正確方法

#execute a select query and return results as a generator 
def SQLSelectGenerator(self,stmt): 
    #error handling code removed 
    cur.execute(stmt) 

    row = "" 
    while row is not None: 
     row = self.cur.fetchone() 
     yield row 

但是,下面也似乎工作,但是它是否執行fetchall()是神祕的。我不能Python的DB API當你迭代的光標對象名單究竟發生在發現:

#execute a select query and return results as a generator 
def SQLSelectGenerator(self,stmt): 
    #error handling code removed 
    cur.execute(stmt) 

for row in self.cur: 
    yield row 

在這兩種情況下,下面的打印所有行成功地

stmt = "select * from ..." 
for l in SQLSelectGenerator(stmt): 
    print(l) 

所以我想知道第二個實現是好還是壞,以及它是調用fetchall還是用fetchone做一些棘手的事情。因爲有數百萬行,Fetchall會炸燬這個系統。

回答

2

按照PyMySql source,做

for row in self.cur: 
    yield row 

含義你在內部執行fetchone()反覆,就像你的第一個例子:

class Cursor(object): 
    ''' 
    This is the object you use to interact with the database. 
    ''' 
    ... 
    def __iter__(self): 
     return iter(self.fetchone, None) 

,所以我期望這兩種方法本質上相等在內存使用和性能方面。你可以使用第二個,因爲它更乾淨簡單。