2017-04-07 74 views
3

我有一個數據文件使用python 2.7中的擱置模塊保存,該數據文件以某種方式損壞。我可以加載它db = shelve.open('file.db'),但是當我打電話len(db)甚至bool(db)它掛起,我必須殺死這個過程。是否有可能檢測到腐敗的Python字典

但是,我能夠遍歷整個事情並創建一個新的非損壞的文件:

db = shelve.open('orig.db') 
db2 = shelve.open('copy.db') 
for k, v in db.items(): 
    db2[k] = v 
db2.close() # copy.db will now be a fully working copy 

的問題是,我如何測試字典,避免掛?

順便說一句,我仍然有原始文件,並且在複製到其他機器時表現出相同的行爲,以防有人也希望幫助我找到文件中實際存在錯誤的底部!

+0

不知道的檢查,也許嘗試一些不同的協議開放http://stackoverflow.com/questions/23582489/python-pickle-protocol-choice也可以在一個子進程中執行,你可以超時 – brennan

回答

1

我不知道除dbm.whichdb()以外的任何檢查方法。爲了調試的方式,可以讓你超時長時間運行測試,可能pickle protocol失配也許嘗試:

import shelve 
import pickle 
import dbm 
import multiprocessing 
import time 
import psutil 

def protocol_check(): 
    print('orig.db is', dbm.whichdb('orig.db')) 
    print('copy.db is', dbm.whichdb('copy.db')) 
    for p in range(pickle.HIGHEST_PROTOCOL + 1): 
     print('trying protocol', p) 
     db = shelve.open('orig.db', protocol=p) 
     db2 = shelve.open('copy.db') 
     try: 
      for k, v in db.items(): 
       db2[k] = v 
     finally: 
      db2.close() 
      db.close() 
     print('great success on', p) 

def terminate(grace_period=2): 
    procs = psutil.Process().children() 
    for p in procs: 
     p.terminate() 
    gone, still_alive = psutil.wait_procs(procs, timeout=grace_period) 
    for p in still_alive: 
     p.kill() 

process = multiprocessing.Process(target=protocol_check) 
process.start() 
time.sleep(10) 
terminate() 
+0

不幸的是,對於工作和損壞的dbs,whichdb()都返回'dbhash'。另外,whichdb是哪個db模塊的python2.7。雖然我喜歡關於超時的想法。 – crazystick

相關問題