2013-02-10 107 views
3

我編寫了一個腳本,用於遍歷大型數據庫表。 (約150K行)。爲了避免使用太多的內存,我使用這個windowed_query method。我的腳本是這樣的:Linux上的Python SQLAlchemy內存泄露

query = db.query(Table) 

count = 0 
for row in windowed_query(query, Table.id, 1000): 

    points = 0 

    # +100 points for a logo 
    if row.logo_id: 
     points += 100 

    # +10 points for each image 
    points += 10 * len(row.images) #images is a SQLAlchemy one-to-many relationship 

    #...The script continues with much of the same... 

    row.points = points 
    db.add(row) 

    count += 1 
    if count % 100 == 0: 
     db.commit() 
     print count 

request.db.commit() 

當嘗試一個CentOS服務器上運行它,它,因爲它的使用使得通過9000行內核被殺前〜2GB的內存

在我的Mac開發環境中,即使它運行在完全相同版本的Python(2.7.3),SQLAlchemy(0.7.8)和psycopg2(2.4.5)上,它也可以像魅力一樣運行。

使用memory_profiler進行一些簡單的調試:在Linux上,查詢數據庫的每段代碼都會增加少量內存,並且增長永不停止。在Mac上,同樣的事情發生了,但是在增長了〜4MB之後,它就趨於穩定。就好像在Linux上一樣,垃圾沒有被收集。 (我甚至嘗試每隔100行運行gc.collect(),沒有做任何事情。)

有沒有人有線索發生了什麼?

+0

也許你正在遭受這個錯誤? http://www.velocityreviews.com/forums/t649192-psycopg2-and-large-queries.html – 2013-02-10 18:59:47

+0

但是'windowed_query'最大的查詢是1000行,所以'fetchall'使用'fetchall'的內存不解釋2GB的內存使用情況。 – 2013-02-10 19:37:01

+3

Aaahhhh ....我想通了。我正在使用Pyramid,並啓用了調試工具欄。禁用它後,內存使用率達到73MB。問題解決了! – 2013-02-10 19:43:58

回答

4

事實證明金字塔的debugtoolbar已啓用,這是高內存使用的原因。我禁用了它,腳本像魅力一樣工作。

+0

是的,大多數調試工具欄都會保存發送給服務器的sql以供以後調試(對Flask的調試工具欄也有類似的樂趣)。 – plaes 2013-12-24 15:04:28