2013-02-10 110 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