在内存高效生成器中使用 PyMySql 的正确方法

Posted

技术标签:

【中文标题】在内存高效生成器中使用 PyMySql 的正确方法【英文标题】:Proper way to use PyMySql in a memory efficient generator 【发布时间】:2014-08-23 17:32:34 【问题描述】:

我想编写一个生成器函数,它将在内存有限的系统上运行,该系统使用 Pymysql(或 MySQLDb)一次返回一个选择查询的结果。以下作品:

#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 将炸毁将要运行的系统,因为有数百万行。

【问题讨论】:

【参考方案1】:

根据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)

所以我希望这两种方法在内存使用和性能方面基本相同。您不妨使用第二个,因为它更简洁。

【讨论】:

以上是关于在内存高效生成器中使用 PyMySql 的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

如何用内存高效的数据结构替换大型 python 字典?

PHP高效率写法

PHP高效率写法

PHP高效率写法

PHP高效率写法

PHP高效率写法