2011-11-25 18 views
1

我有32 SQLite的(3.7.9)的數據庫,每3個表,我試圖用我已經找到其他地方的成語合併在一起(每個數據庫具有相同的架構):合併SQLite數據庫讓我很生氣。幫幫我?

attach db1.sqlite3 as toMerge; 
insert into tbl1 select * from toMerge.tbl1; 
insert into tbl2 select * from toMerge.tbl2; 
insert into tbl3 select * from toMerge.tbl3; 
detach toMerge; 

和整套數據庫的沖洗重複。我爲此使用python和sqlite3的模塊:

for fn in filelist: 

    completedb = sqlite3.connect("complete.sqlite3") 
    c = completedb.cursor() 

    c.execute("pragma synchronous = off;") 
    c.execute("pragma journal_mode=off;") 

    print("Attempting to merge " + fn + ".") 
    query = "attach '" + fn + "' as toMerge;" 
    c.execute(query) 

    try: 
     c.execute("insert into tbl1 select * from toMerge.tbl1;") 
     c.execute("insert into tbl2 select * from toMerge.tbl2;") 
     c.execute("insert into tbl3 select * from toMerge.tbl3;") 
     c.execute("detach toMerge;") 
     completedb.commit() 
    except sqlite3.Error as err: 
     print "Error! ", type(err), " Error msg: ", err 
     raise 

2的表是相當小,只有50K每分貝行,而第三個(TBL3)越大,約850 - 900K行。現在,會發生什麼情況是,插入逐漸減慢,直到我們到達第四個數據庫時(即每隔1-3分鐘添加一個兆字節或兩個文件大小)。如果是python,我甚至試着用INSERT(.insert; .out foo; sqlite3 complete.db < foo是骨架,找到here)並將它們在使用sqlite3 CLI的bash腳本中合併爲直接做這項工作,但我得到完全相同的問題。

tbl3的表格設置不是太苛刻 - 包含UUID,兩個整數和四個實數值的文本字段。我擔心的是這是行數,因爲當單個數據庫的文件大小相差數量級相同且行數相同時,我在同一個地點(大約四個數據庫)遇到了完全相同的問題(我通過存儲摘要統計數據而非原始數據來顯着減少tbl3的內容)。或者也許這是我執行操作的方式?任何人都可以在我把這些東西扔出窗外之前解釋一下這個問題嗎?

回答

1

你沒有提到你正在使用的操作系統或db文件大小。 Windows可能會遇到大於2Gb的文件,具體取決於版本。

在任何情況下,因爲這是一個榮耀的批處理腳本,爲什麼不擺脫for循環,從sys.argv獲得文件名,然後爲每個合併數據庫運行一次。這樣你就不必在一個過程中處理太多的內存問題。

請注意,如果您以下列方式結束循環,可能也會修復問題。

c.close() 
completedb.close() 

你說當你按照這個過程使用CLI並在每個數據庫之後退出時會發生同樣的事情。我假定你的意思是Python CLI,退出意味着你退出並重新啓動Python。如果這是真的,並且它每隔4個數據庫仍然會出現問題,那麼SQLITE共享庫會出現問題。它不應該保持那樣的狀態。

如果我在你的鞋子裏,我會停止使用attach,只需在Python中打開多個連接,然後每次提交大約1000條記錄的批量移動數據。它會比你的技術慢,因爲所有的數據進出Python對象,但我認爲它也會更可靠。打開完整的數據庫,然後循環打開第二個數據庫,複製,然後關閉第二個數據庫。對於複製,我會在SELECT語句中使用OFFSET和LIMIT來處理100個記錄的批次,然後提交,然後重複。 事實上,我也會在複製之前計算完成的b記錄和第二個db記錄,然後在複製之後計算完成的b記錄以確保我複製了預期的數量。另外,您將跟蹤下一個OFFSET的值,並在提交後立即將其寫入文本文件,以便隨時中斷並重新啓動該進程,並且該進程將繼續停止。

+0

Michael,謝謝你的回答。 Re:你的問題,我已經在OS X Lion上和Rocks集羣的頭節點上試過了(5.3)。正如我所提到的,問題與數據庫文件大小無關;在目前的版本中,它們每個都是160Mb,但是當它們每個是1.6Gb時,問題的發生方式完全相同。重新提出您的建議:我之前嘗試使用c.close()和completedb.close(),但將其從此代碼中排除 - 它沒有解決問題。我甚至嘗試過使用CLI手動完成 - 啓動它,附加,合併,退出,然後重複每個文件。沒有運氣。 – Winawer

1

嘗試添加或刪除較大表的索引/主鍵。