在Python中复制光标对象

2024-05-16 00:03:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个Trac插件。。。

为了检索我的数据,我创建了一个cursor对象并得到如下的结果表:

 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)。

我怎样才能解决这个问题?


Tags: 数据对象函数orgselfenv插件http
2条回答

存储任何有限iterable中的值很简单:

results = list(cursor)

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

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

对于这种特定的情况,您应该按照9000在他的注释中的建议来做——使用内置的游标功能来获得列表的结果,这应该与手动调用list一样快或更快。

如果要避免在额外的时间循环数据,可以尝试将其包装在生成器中:

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"

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

我想如果我要争论使用这个,我会使用相同的names参数,除非数据集相当大,但是如果它足够大,可以很好地解决问题,那么无论如何你都不想把它存储在内存中。

而且它完全没有经过测试。

相关问题 更多 >