是的,我已經使用sqlite3這種事情。字典值必須首先被醃製:
import sqlite3
import pickle
import collections
class DBDict(collections.MutableMapping):
'Database driven dictlike object (with non-persistent in-memory option).'
def __init__(self, db_filename=':memory:', **kwds):
self.db = sqlite3.connect(db_filename)
self.db.text_factory = str
try:
self.db.execute('CREATE TABLE dict (key text PRIMARY KEY, value text)')
self.db.execute('CREATE INDEX key ON dict (key)')
self.db.commit()
except sqlite3.OperationalError:
pass # DB already exists
self.update(kwds)
def __setitem__(self, key, value):
if key in self:
del self[key]
value = pickle.dumps(value)
self.db.execute('INSERT INTO dict VALUES (?, ?)', (key, value))
self.db.commit()
def __getitem__(self, key):
cursor = self.db.execute('SELECT value FROM dict WHERE key = (?)', (key,))
result = cursor.fetchone()
if result is None:
raise KeyError(key)
return pickle.loads(result[0])
def __delitem__(self, key):
if key not in self:
raise KeyError(key)
self.db.execute('DELETE FROM dict WHERE key = (?)', (key,))
self.db.commit()
def __iter__(self):
return iter([row[0] for row in self.db.execute('SELECT key FROM dict')])
def __repr__(self):
list_of_str = ['%r: %r' % pair for pair in self.items()]
return '{' + ', '.join(list_of_str) + '}'
def __len__(self):
return len(list(iter(self)))
>>> d = DBDict(raymond='red', rachel='blue')
>>> d
{'rachel': 'blue', 'raymond': 'red'}
>>> d['critter'] = ('xyz', [1,2,3])
>>> d['critter']
('xyz', [1, 2, 3])
>>> len(d)
3
>>> list(d)
['rachel', 'raymond', 'critter']
>>> d.keys()
['rachel', 'raymond', 'critter']
>>> d.items()
[('rachel', 'blue'), ('raymond', 'red'), ('critter', ('xyz', [1, 2, 3]))]
>>> d.values()
['blue', 'red', ('xyz', [1, 2, 3])]
以上將使您的數據庫保持在單個文件中。您可以像普通的Python字典一樣瀏覽對象。由於這些值在單個字段中進行了pickle,因此sqlite不會爲您提供任何其他查詢選項。其他平面文件存儲將具有類似的限制。如果您需要編寫遍歷分層結構的查詢,請考慮使用NoSQL數據庫。
ZODB是一個對象數據庫,它是在Zope框架中執行和驗證的 – aitchnyu