2012-06-05 36 views
1

以下是我在代码中使用的常见模式,我更想知道游标和连接的内部。关于打开和关闭游标和连接的建议练习

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

与数据库的连接和游标的区别是什么?开放连接有什么不利之处(例如,几分钟?)。怎么样有未关闭的游标,有什么影响?当连续执行多个SQL语句时,是否应该每次创建一个新的游标?

+0

哪种语言是这样一个背景下,经理这样? – Sebas

+0

@Sebas python ......... – David542

+0

如果游标将被重新使用,我通常会将其打开。这是一个不活跃的数据库会话,只要没有太多的游标保持打开状态,那么就不会对服务器产生影响,并且不会导致连续打开和关闭以及重新打开等。 – Ben

回答

1

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

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

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

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

+0

错误;游标不是类似于迭代器的东西,游标是驱动程序所做的任何事情。至少在MySQL中,无论如何,整个结果集通常都在内存中。 – MarkR

3

它取决于底层实现 - Cursor对象实际上是在驱动程序内部。在许多DB-api实现中,Cursor对象不是“有趣的”(即,你可以保留它们很多,让GC担心它们),特别是如果你还没有完成返回结果集的查询。

我还没有和Oracle一起使用过Python,但我怀疑(根据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 
+0

你有没有机会检查它是否适用于MySQLDB? –