Django的cursor
類僅僅是底層數據庫的cursor
的一個包裝,因此打開cursor
的效果基本上與底層數據庫驅動程序有關。
根據psycopg2的(psycopg2是DB驅動Django使用PostgreSQL的DB的)FAQ,他們的遊標是輕量級的,但將緩存從你使用遊標對象進行查詢返回的數據,這可能會浪費內存:
遊標是輕量級的對象,並創造大量的人不應該 帶來什麼樣的問題。但請注意,用於獲取結果 集合的遊標將緩存數據並根據結果 集合大小成比例地使用內存。我們的建議是幾乎總是創建一個新的光標, 儘快處置舊如不再需要的數據(稱之爲 他們的close())。唯一的例外是緊密的循環,其中一個通常 使用相同的光標的全部插入或更新。
Django使用MySQLdb
作爲後端的MySQL,它有幾種不同類型的遊標,包括一些實際的結果集存儲在服務器端。該MySQLdb
documentation for Cursor.close
做出一點要注意,它關閉是非常重要的服務器端遊標時,你與他們做的:
如果您正在使用服務器端遊標,這是非常重要的,關閉 光標當你完成它並在創建一個新的之前。
然而,這是不相關的Django的,因爲它使用MySQLdb
提供的默認Cursor
類,存儲在客戶端的結果。將使用的光標保留在開啓位置可能會浪費存儲結果集使用的內存,就像psycopg2
一樣。光標的close
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
類有密切的方法,而且只有在所包含的示例代碼使用斷斷續續。
你是正確的,當__del__()
被稱爲cursor
對象上的cursor
將被關閉,所以需要顯式關閉只是,如果你保持長壽的參考cursor
的問題;例如一個self.cursor
對象,你保留作爲一個類的實例方法。
我想這是非常相似的這個問題http://stackoverflow.com/questions/5669878/python-mysqldb-when-to-close-cursors? –
@AamirAdnan非常感謝,在發帖前看到它。我知道如何關閉光標。問題是關閉它有多糟,以及後果如何。 – alecxe