2013-04-04 85 views
0

我有一個小型Python 2.7腳本,它使用LIKE語句從存儲在SQLite數據庫中的文本數據中提取信息片段。從大型數據庫(> 1GB)讀取SQLite3內存錯誤

sql = "SELECT user_id, loc,\ 
     FROM entity\ 
     WHERE loc LIKE '%\"place\":%'\ 
     AND loc LIKE '%\"geo\":%'\ 
    AND loc LIKE '%\"coordinates\":%'" 
cin.execute(sql) 
entities = cin.fetchall() 

cin是光標到SQLite數據庫(表entity具有> 10^6行)(〜1.5GB),將其使用

import sqlite3 
try: 
    dbin = sqlite3.connect(database=args['dbi'].name) 
    dbin.row_factory = sqlite3.Row 
    cin = dbin.cursor() 
except sqlite3.Error, e: 
    errorLogger.error('... %e' % e) 
    sys.exit() 

腳本運行良好爲10數據庫大小建立^ 2 MB,但現在我得到一個

Traceback (most recent call last): 
    File "C:\Users\...\migrate.py", line 247, in <module> 
    entities = cin.fetchall() 
MemoryError 

幾秒鐘後。 我正在運行一臺W7 64位機,內存爲8GB RAM。當腳本運行時,通過查看W7的資源監視器,我可以看出,在程序崩潰之前,所有可用內存都被使用,並且python.exe消耗高達1.9GB。儘管如此,還有大約3GB的待機內存可用(但不要問我待機和可用內存之間有什麼區別)。

除了對我的查詢進行預過濾之外,我還能做些什麼?通過僅查看,比方說,每個查詢10'000行?

+1

爲什麼不使用'''''三重引號而不是所有的反斜槓? – 2013-04-04 20:11:51

+0

你真的需要調用'fetchall()'嗎?看起來你有太多的結果,你可以迭代遊標並逐行處理這些行,而不是將它們全部加載到內存中。 – 2013-04-04 20:13:16

+0

獲得更多記憶? – 2013-04-04 20:24:46

回答

2

調用fetchall需要爲所有結果記錄分配內存。

您應該逐個閱讀cin的結果記錄。

+0

非常感謝這個提示,我認爲所有的提取都會在'execute'函數內發生,因此使用'fetchone'或'fetchall'無關緊要,但是你證明我錯了。奇蹟般有效。 – wnstnsmth 2013-04-05 06:48:47