1

以下是我的代码中的一个常见模式,我想知道更多关于游标和连接的内部结构。

cursor = connection.cursor()
cursor.execute("SET NAMES utf8")
cursor.execute(sql, args)
results = cursor.fetchall()
cursor.close()

到数据库的连接和游标之间有什么区别?开放连接是否有任何缺点(例如,几分钟?)。有未关闭的游标怎么办,有什么影响?连续执行多条SQL语句时,每次都要新建一个游标吗?

4

2 回答 2

3

这取决于底层实现——Cursor 对象在驱动程序中的实际内容。

在许多 DB-api 实现中,Cursor 对象并不“有趣”(即,您可以保留很多对象并让 GC 担心它们),尤其是在您没有执行返回结果集的查询时。

我没有将 Python 与 Oracle 一起使用,但我怀疑(基于 JDBC 和其他方面的经验)Oracle 并非如此。Oracle JDBC 驱动程序具有服务器端游标,快速关闭它非常重要(默认的每个连接游标限制相当低;超过限制会导致尝试打开另一个游标失败)。

在 Oracle 中,依靠 GC 关闭游标可能是危险的,例如,如果您在循环中打开一个新游标,而 GC 将它们全部保留,直到循环函数返回。

如果这是真的,那么使用 with 语句构造来确保游标及时关闭可能会有所帮助,即使发生异常也是如此。


更新:您可以使用 contextlib.closure 作为上下文管理器,例如

with contextlib.closing(myconnection.cursor()) as curs:
  curs.execute(...
  # even if exception happens, cursor is still closed immediately 
  # after this block
于 2012-06-05T21:05:14.257 回答
1

游标类似于 python 中的迭代器。它使您能够遍历结果集,而无需将其全部保存在内存中。对于您使用的每个 RDBMS,可以以不同的方式实现光标。

如果垃圾收集器不删除它,未关闭的游标将使用一些内存。

您可以在一个连接中打开多个游标。

您可以保持连接打开。根据您使用的数据库,打开连接将使用一些资源,并且一次可以打开多少个连接可能会受到限制。

于 2012-06-05T21:03:56.103 回答