有时,我使用connection.cursor()来执行原始查询,而不是使用ORM (因为它绝对不是一个灵丹妙药)。
我注意到,在处理完数据库之后,有几个地方我不调用显式cursor.close()。到目前为止,这还没有导致任何错误,或性能问题。我在想,如果不显式地关闭光标,我可能会遇到什么样的问题呢?
据我所知,Django中的connection和cursor遵循"Python规范v2.0“(佩普-249)。而且,根据它,每当调用cursor方法时,__del__()都会自动关闭。我想问题也可能是:当不调用用例时,是否存在用例?
FYI,我使用Python2.7和Django 1.6.5。
发布于 2014-07-18 15:09:30
__del__**/**.close()**:**
__del____del__ (错误的实践,而是正确的)。服务器连接上的(一般为)
大多数服务器都具有空闲超时配置属性(让我们称之为T)。如果连接空闲时间超过T秒,服务器将删除连接。大多数服务器还具有设置工作线程池(W)大小的属性。如果您已经有到服务器的W连接,则在尝试新连接时可能会挂起。第二,假设您没有显式关闭连接的选项。在这种情况下,您必须将超时设置为足够小,使您的工作池永远不会被完全使用,这取决于您有多少并发连接。
但是,如果您确实关闭了游标/连接(即使在上面没有对应的情况下,它们以类似的方式运行),那么您就不必管理这些服务器配置属性,您的线程池只需足够大来管理所有并发连接(可以选择偶尔等待新的资源)。我已经看到一些服务器(例如,Cassandra上的Titan )无法从线程池中耗尽的工作人员中恢复过来,所以直到重新启动整个服务器才能恢复。
TL/DR如果您使用的是非常完善的库,如dano提到的库,您就不会有问题。如果您使用的是不太原始的库,那么如果不调用.close(),则可能会阻塞服务器上的工作线程,这取决于服务器配置和访问速率。
发布于 2014-07-09 19:48:09
Django的cursor类只是底层DB的cursor的包装器,因此保持cursor打开的效果基本上与底层DB驱动程序绑定在一起。
根据psycopg2的常见问题( PostgreSQL是DB驱动程序Django使用的) 常见问题,它们的游标是轻量级的,但是会缓存从使用游标对象进行的查询中返回的数据,这可能会浪费内存:
游标是轻量级对象,创建大量游标不应造成任何问题。但是请注意,用于获取结果集的游标将缓存数据并根据结果集大小使用内存。我们的建议是,当数据不再需要时,几乎总是创建一个新的游标并处理旧的游标(对它们调用close() )。唯一的例外是紧循环,在这种情况下,通常会使用相同的游标来执行大量的插入或更新。
Django使用MySQLdb作为MySQL的后端,它有几种不同类型的游标,包括一些实际上将结果集存储在服务器端的游标。Cursor.close指出,当您完成这些操作时关闭服务器端游标是非常重要的:
如果您使用的是服务器端游标,那么在使用完游标和创建新游标之前关闭游标是非常重要的。
但是,这与Django无关,因为它使用了由Cursor提供的默认MySQLdb类,它将结果存储在客户端。将已使用的游标保持打开只会浪费存储结果集所使用的内存,就像psycopg2一样。游标上的方法只删除对db连接的内部引用并耗尽存储的结果集:
def close(self):
"""Close the cursor. No further queries will be possible."""
if not self.connection: return
while self.nextset(): pass
self.connection = None从查看它们的源代码可以看出,Django (甲骨文,sqlite3/pysqlite2)使用的所有剩余后端都遵循相同的模式;通过删除/重置存储的结果/对象引用释放内存。sqlite3文档甚至没有提到Cursor类有一个close方法,它仅在包含的示例代码中偶尔使用。
您是正确的,当在cursor对象上调用__del__()时,cursor将被关闭,因此,只有在保持对cursor的长期引用的情况下,显式关闭的需要才是一个问题;例如,作为类的实例方法而保留的self.cursor对象。
https://stackoverflow.com/questions/24661754
复制相似问题