Django的cursor类只是底层DB的cursor的包装,因此保持cursor打开的效果基本上与底层DB驱动程序相关。
根据psycopg2(psycopg2是Django用于PostgreSQL数据库的数据库驱动程序)FAQ,它们的游标是轻量级的,但会缓存使用游标对象进行查询时返回的数据,这可能会浪费内存:Cursors are lightweight objects and creating lots of them should not
pose any kind of problem. But note that cursors used to fetch result
sets will cache the data and use memory in proportion to the result
set size. Our suggestion is to almost always create a new cursor and
dispose old ones as soon as the data is not required anymore (call
close() on them.) The only exception are tight loops where one usually
use the same cursor for a whole bunch of INSERTs or UPDATEs.
Django使用MySQLdb作为MySQL的后端,MySQL有几种不同类型的游标,包括一些实际将结果集存储在服务器端的游标。^{} documentation for ^{}指出,在完成这些操作后,关闭服务器端光标非常重要:If you are using server-side cursors, it is very important to close
the cursor when you are done with it and before creating a new one.
但是,这与Django无关,因为它使用由MySQLdb提供的默认Cursor类,该类在客户端存储结果。打开已使用的游标只会浪费存储结果集使用的内存,就像psycopg2。光标上的^{} method只会删除对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使用的所有剩余后端(cx_oracle,sqlite3/pysqlite2)都遵循相同的模式;通过删除/重置存储的结果/对象引用来释放内存。sqlite3 docs甚至没有提到Cursor类有一个close方法,它只在包含的示例代码中偶尔使用。
当对cursor对象调用__del__()时,cursor将被关闭,这是正确的,因此,如果要长期保持对cursor的引用(例如,作为类的实例方法而保留的self.cursor对象),则只需要显式关闭。