以下是我的代码中常见的模式,我想知道更多关于游标和连接的内部结构。
cursor = connection.cursor()
cursor.execute("SET NAMES utf8")
cursor.execute(sql, args)
results = cursor.fetchall()
cursor.close()
与数据库的连接和游标之间有什么区别?打开连接是否存在任何缺点(例如,几分钟?)。如果有非封闭游标,效果如何?当连续执行多个SQL语句时,每次都应该创建一个新的游标吗?
答案 0 :(得分:3)
它取决于底层实现 - Cursor对象实际上在驱动程序内部。
在许多DB-api实现中,Cursor对象不是“有趣”(即你可以保留很多它们并让GC担心它们),特别是如果你还没有完成返回结果集的查询。
我没有将Python与Oracle一起使用,但我怀疑(基于对JDBC和其他人的经验)在Oracle中并非如此。 Oracle JDBC驱动程序具有服务器端游标,快速关闭至关重要(每个连接的游标限制默认值相当低;超出限制会导致尝试打开另一个游标失败)。
在Oracle中,依赖GC关闭游标可能会有危险,例如,如果您在循环中打开一个新游标并且GC将其全部保留,直到循环函数返回。
如果这是真的,使用with-statement构造确保光标及时关闭可能会有所帮助,即使发生异常也是如此。
更新:您可以使用contextlib.closing作为上下文管理器,例如
with contextlib.closing(myconnection.cursor()) as curs:
curs.execute(...
# even if exception happens, cursor is still closed immediately
# after this block
答案 1 :(得分:1)
Cursor类似于python中的迭代器。它使您能够遍历结果集而不将其保留在内存中。对于您正在使用的每个RDBMS,可以以不同方式实现游标。
如果垃圾回收器没有删除它,未封闭的游标将使用一些内存。
您可以在一个连接中打开多个光标。
您可以保持连接打开。根据您使用的数据库,打开连接将使用一些资源,并且可以限制一次可以打开多少协议。