在Python中复制游标对象

时间:2012-04-16 13:56:12

标签: python cursor deep-copy

我正在制作Trac-Plugin ......

要检索我的数据,我创建一个游标对象并获取结果表,如下所示:

 db = self.env.get_db_cnx()
 cursor = db.cursor()
 cursor.execute("SELECT...") 

现在结果用于3种不同的功能。我的问题是现在光标在第一次循环时被清理掉(就像在http://packages.python.org/psycopg2/cursor.html这里说的那样)

然后我尝试复制光标对象,但这也失败了。 copy(cursor)函数似乎对大数据集有问题,函数deepcopy(cursor)无论如何都会失败(根据此错误http://bugs.python.org/issue1515)。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:12)

存储来自任何有限可迭代的值很简单:

results = list(cursor)

迭代迭代并将结果存储在列表中。这个列表可以根据需要重复多次。

您不需要光标的副本,只需要查询结果的副本。

对于这种特定情况,您应该执行9000在其评论中建议的内容 - 使用游标内置功能来获取列表的结果,该列表的结果应该比手动调用list快或快。

答案 1 :(得分:0)

如果您想避免在数据中循环,可以尝试将其包装在生成器中:

def lazy_execute(sql, cursor=cursor):
    results = []
    cursor.execute(sql)
    def fetch():
        if results:
            for r in results:
                yield r
            raise StopIteration()
        else:
            for r in cursor:
                results.append(r)
                yield r
            raise StopIteration()

    return fetch

这基本上可以根据需要创建一个列表,但是可以安全地在任何地方调用相同的函数。然后你会这样使用它:

results = lazy_execute(my_sql):
for r in results():
    "do something with r"

这几乎可以肯定是一种过度设计的过早优化,尽管它确实具有相同名称的优点,在每种情况下都具有相同的意义,而不是生成新列表,然后是具有两个不同名称的相同数据。

我认为如果我打算使用这个,我会使用相同的名称参数,除非数据集非常大,但如果它足够重要,那么很有可能你不想存储无论如何,这一切都在记忆中。

它也完全未经测试。