我正在制作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)。
我该如何解决这个问题?
答案 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"
这几乎可以肯定是一种过度设计的过早优化,尽管它确实具有相同名称的优点,在每种情况下都具有相同的意义,而不是生成新列表,然后是具有两个不同名称的相同数据。
我认为如果我打算使用这个,我会使用相同的名称参数,除非数据集非常大,但如果它足够重要,那么很有可能你不想存储无论如何,这一切都在记忆中。
它也完全未经测试。