市面上已经有很优秀的嵌入式KV数据库了,如Berkeley DB。为什么还需要把Sqlite当KV数据库用呢?原因若干。
1,可能是为了好玩或者纯属无聊
2,可结合关系型数据库与KV数据库的优点
3,可利用一些sqlite特性做其他KV数据库不好做的事情
4,事务管理更方便
5,sqlite更可靠,更流行
实现思路
使用json(或pickle)dump数据,并将数据写入有KEY(主键)和VALUE两个字段的SQLITE库表中。参照kv数据库调用办法实现外部接口。
主要功能
1,put:写入key/value数据
2,get:获取某个key的value
3,put_many:批量写入key/value数据
4,keys:获取所有key的列表
5,value:获取所有value的列表
6,limit:利用SQL语句中limit关键字,获取数据库中“前”N条KV数据
7,random:利用SQL语句中random关键字,从数据库中随即获取N条KV数据
8,has_key:某个key是否存在
9,cursor_execute:执行sql自定义语句
10,其他:items,pop,filter,count等
代码(KVSqlite.py):
import os, json, sqlite3
from threading import Lock
PY3 = os.sys.version_info >= (3,)
if PY3:
ifilter = filter
else:
from itertools import ifilter
DUMPS = lambda d: json.dumps(d)
LOADS = lambda d: json.loads(d)
class SDB(object):
_DEFAULT_TABLE = '__KVS_DEFAULT_TABLE__'
_MEMORY_DB = ":memory:"
def __init__(self, filename):
if filename is None \
or len(filename) < 1 \
or filename.lower() == self._MEMORY_DB:
self.filename = self._MEMORY_DB
else:
self.filename = filename
self._lock = Lock()
self._db_init()
def _row_factory(self, cursor, row):
result = []
for idx, col in enumerate(cursor.description):
if col[0].lower() in ('k', 'v'):
result.append(LOADS(row[idx]))
else:
result.append(row[idx])
return result
def _db_init(self):
_new_table = "CREATE TABLE IF NOT EXISTS {0} ( k PRIMARY KEY,v)".format(self._DEFAULT_TABLE)
db = sqlite3.connect(self.filename, timeout=60, check_same_thread=False)
db.row_factory = self._row_factory
db.execute(_new_table)
self._cursor = db.cursor()
self._db = db
def _statement_init(self):
table = self._DEFAULT_TABLE
return dict(insert="insert or replace into {0}(k,v) values(:1,:2)".format(table),
delete="delete from {0} where k=:1".format(table),
update="update {0} set v=:1 where k=:2".format(table),
clear="delete from {0}".format