使用 SQLite 作为 key:value 存储
Use SQLite as a key:value store
正如 的评论和其他问题中所建议的,SQLite 完全可以用作持久性 key:value 存储。
您将如何定义一个 class(或只是包装函数),以便将 key:value 存储与 SQLite 一起使用就像这样简单:
kv = Keyvaluestore('/test.db')
kv['hello'] = 'hi' # set
print(kv['hello']) # get
print('blah' in kv) # answer: False because there's no key 'blah' in the store
kv.close()
?
已经有 sqlitedict 似乎可以满足您的所有需求。
来自文档:
from sqlitedict import SqliteDict
mydict = SqliteDict('./my_db.sqlite', autocommit=True)
mydict['some_key'] = any_picklable_object
print(mydict['some_key']) # prints the new value
for key, value in mydict.iteritems():
print(key, value)
print(len(mydict)) # etc... all dict functions work
mydict.close()
即使存在执行此操作的模块(请参阅其他答案),我也尝试编写一个简单、独立的版本。这是一个 class KeyValueStore
(键和值是字符串),其工作方式如下:
演示
from sqlitekeyvaluestore import KeyValueStore
kv = KeyValueStore('test.db') # uses SQLite
print(len(kv)) # 0 item
kv['hello1'] = 'you1'
kv['hello2'] = 'you2'
kv['hello3'] = 'you3'
print(kv['hello1']) # you1
print(len(kv)) # 3 items
del kv['hello1']
print(len(kv)) # 2 items remaining
print('hello1' in kv) # False, it has just been deleted!
print('hello3' in kv) # True
kv['hello3'] = 'newvalue' # redefine an already present key/value
print(kv['hello3']) # newvalue
print(kv.keys()) # ['hello2', 'hello3']
print(kv.values()) # ['you2', 'newvalue']
print(kv.items()) # [('hello2', 'you2'), ('hello3', 'newvalue')]
for k in kv:
print(k, kv[k])
kv.close() # important to commit
代码:sqlitekeyvaluestore.py
import sqlite3
class KeyValueStore(dict):
def __init__(self, filename=None):
self.conn = sqlite3.connect(filename)
self.conn.execute("CREATE TABLE IF NOT EXISTS kv (key text unique, value text)")
def close(self):
self.conn.commit()
self.conn.close()
def __len__(self):
rows = self.conn.execute('SELECT COUNT(*) FROM kv').fetchone()[0]
return rows if rows is not None else 0
def iterkeys(self):
c = self.conn.cursor()
for row in c.execute('SELECT key FROM kv'):
yield row[0]
def itervalues(self):
c = self.conn.cursor()
for row in c.execute('SELECT value FROM kv'):
yield row[0]
def iteritems(self):
c = self.conn.cursor()
for row in c.execute('SELECT key, value FROM kv'):
yield row[0], row[1]
def keys(self):
return list(self.iterkeys())
def values(self):
return list(self.itervalues())
def items(self):
return list(self.iteritems())
def __contains__(self, key):
return self.conn.execute('SELECT 1 FROM kv WHERE key = ?', (key,)).fetchone() is not None
def __getitem__(self, key):
item = self.conn.execute('SELECT value FROM kv WHERE key = ?', (key,)).fetchone()
if item is None:
raise KeyError(key)
return item[0]
def __setitem__(self, key, value):
self.conn.execute('REPLACE INTO kv (key, value) VALUES (?,?)', (key, value))
def __delitem__(self, key):
if key not in self:
raise KeyError(key)
self.conn.execute('DELETE FROM kv WHERE key = ?', (key,))
def __iter__(self):
return self.iterkeys()
我喜欢 Basj 的回答,
但我还想在 KeyValueStore class 中添加以下函数,以便在使用数据库时,我们可以提交数据而不必关闭数据库。
class KeyValueStore(dict):
"""Other functions"""
def commit(self):
self.conn.commit()
sqlite3dbm 提供此功能,同时保留传统的 dbm 界面。它是一个比 sqlitedict 更简单的界面,当你只需要一个非常基本的 key-value 商店时。它还包括一个方便的 class,可以使用 python 的 shelve
功能将任意对象存储为值。
正如
您将如何定义一个 class(或只是包装函数),以便将 key:value 存储与 SQLite 一起使用就像这样简单:
kv = Keyvaluestore('/test.db')
kv['hello'] = 'hi' # set
print(kv['hello']) # get
print('blah' in kv) # answer: False because there's no key 'blah' in the store
kv.close()
?
已经有 sqlitedict 似乎可以满足您的所有需求。
来自文档:
from sqlitedict import SqliteDict
mydict = SqliteDict('./my_db.sqlite', autocommit=True)
mydict['some_key'] = any_picklable_object
print(mydict['some_key']) # prints the new value
for key, value in mydict.iteritems():
print(key, value)
print(len(mydict)) # etc... all dict functions work
mydict.close()
即使存在执行此操作的模块(请参阅其他答案),我也尝试编写一个简单、独立的版本。这是一个 class KeyValueStore
(键和值是字符串),其工作方式如下:
演示
from sqlitekeyvaluestore import KeyValueStore
kv = KeyValueStore('test.db') # uses SQLite
print(len(kv)) # 0 item
kv['hello1'] = 'you1'
kv['hello2'] = 'you2'
kv['hello3'] = 'you3'
print(kv['hello1']) # you1
print(len(kv)) # 3 items
del kv['hello1']
print(len(kv)) # 2 items remaining
print('hello1' in kv) # False, it has just been deleted!
print('hello3' in kv) # True
kv['hello3'] = 'newvalue' # redefine an already present key/value
print(kv['hello3']) # newvalue
print(kv.keys()) # ['hello2', 'hello3']
print(kv.values()) # ['you2', 'newvalue']
print(kv.items()) # [('hello2', 'you2'), ('hello3', 'newvalue')]
for k in kv:
print(k, kv[k])
kv.close() # important to commit
代码:sqlitekeyvaluestore.py
import sqlite3
class KeyValueStore(dict):
def __init__(self, filename=None):
self.conn = sqlite3.connect(filename)
self.conn.execute("CREATE TABLE IF NOT EXISTS kv (key text unique, value text)")
def close(self):
self.conn.commit()
self.conn.close()
def __len__(self):
rows = self.conn.execute('SELECT COUNT(*) FROM kv').fetchone()[0]
return rows if rows is not None else 0
def iterkeys(self):
c = self.conn.cursor()
for row in c.execute('SELECT key FROM kv'):
yield row[0]
def itervalues(self):
c = self.conn.cursor()
for row in c.execute('SELECT value FROM kv'):
yield row[0]
def iteritems(self):
c = self.conn.cursor()
for row in c.execute('SELECT key, value FROM kv'):
yield row[0], row[1]
def keys(self):
return list(self.iterkeys())
def values(self):
return list(self.itervalues())
def items(self):
return list(self.iteritems())
def __contains__(self, key):
return self.conn.execute('SELECT 1 FROM kv WHERE key = ?', (key,)).fetchone() is not None
def __getitem__(self, key):
item = self.conn.execute('SELECT value FROM kv WHERE key = ?', (key,)).fetchone()
if item is None:
raise KeyError(key)
return item[0]
def __setitem__(self, key, value):
self.conn.execute('REPLACE INTO kv (key, value) VALUES (?,?)', (key, value))
def __delitem__(self, key):
if key not in self:
raise KeyError(key)
self.conn.execute('DELETE FROM kv WHERE key = ?', (key,))
def __iter__(self):
return self.iterkeys()
我喜欢 Basj 的回答, 但我还想在 KeyValueStore class 中添加以下函数,以便在使用数据库时,我们可以提交数据而不必关闭数据库。
class KeyValueStore(dict):
"""Other functions"""
def commit(self):
self.conn.commit()
sqlite3dbm 提供此功能,同时保留传统的 dbm 界面。它是一个比 sqlitedict 更简单的界面,当你只需要一个非常基本的 key-value 商店时。它还包括一个方便的 class,可以使用 python 的 shelve
功能将任意对象存储为值。