python 持久化键值存储数据库
0 背景
在运行一些python程序时, 有时需要临时且持久化存储一些简单的变量, 不适合放在内存中, 但因为其简单有不需要特别去引用一个数据库(比如redis), 因此我们可以使用DBM去实现我们的需求.
什么是DBM?
DBM(DataBase Manager)是一种文件系统,专用于键值对的存储. 对于 Key-Value 模型,DBM 提供了一个轻量级、高效的存储解决方案。
DBM 具有如下特点:
-
简单快速:读取和写入操作都很快,适合存储少量数据。 -
键值对存储:数据以键值对形式存储的,我们可以像操作Python 字典一样。 -
文件存储:数据存在具体的文件中,可以轻松地备份和转移。
python 提供了自带的dbm
模块, 可以帮助我们实现最简单的key-value存储, 但只能实现字符串或字节类型的存储; shelve
也是python自带的KV数据库, 可以实现存储列表, 字典等复杂的存储; diskcache
是一个第三方库, 相比于shelve
, 它同样可以实现列表, 字典等更复杂的对象的存储, 同时, 可以支持设置变量的有效时间, 这一点是可以对标redis的, 当然还有其他功能, 后面细说.
1 dbm
dbm
是python的一个标准库, 它实现了 DBM 文件系统的功能, 使用方式上和我们日常使用python的dict
字典用法基本一致.
import dbm
db_path = 'example.db'
db = dbm.open(db_path, 'c')
db['name'] = 'orange'
db.get('name').decode()
db.get('language').decode()
db.get('language', b'zh-CN').decode()
db.close()
db的基本用法如下, 基本和dict
保持一致:
clear
close
get
items
iterkeys
keys
pop
popitem
setdefault
sync
update
values
另外, dbm
也有几种操作模式如下:
r
:只读,要求文件必须存在,默认就是这个模式.w
:可读可写,要求文件必须存在.c
:可读可写,文件不存在会创建,存在则追加.n
:可读可写,文件不存在会创建,存在则清空.
如果需要保存int
类型的数据, 还需要将int
转为字符串,如果需要保存list
或dict
这种类型的数据, 可以通过json.dumps()
转换为json进行保存。
在 dbm
模块存储的键和值必须是字符串或可以被转换为字符串的对象。在存储和检索时,我们还需要使用encode
和decode
方法将数据转换为字节字符串和普通字符串。
2 shelve
shelve
的操作方式和dbm
基本是类似的, 但是shelve
的序列化能力更加强大.
import shelve
sh = shelve.open('orange_shelve', 'c')
sh['name'] = 'orange'
sh['age'] = 18
sh['info'] = {'height': 188, 'weight': 60, 'pwd': 'orange'}
sh['hobby'] = ['sing', 'dance', 'rap', 'basketball']
当我们读取的时候, 可以正常返回原类型的数据.
sh['hobby']
# ['sing', 'dance', 'rap', 'basketball']
sh['info']
# {'height': 188, 'weight': 60, 'pwd': 'orange'}
最后, 记得执行close()
写入到本地.
sh.close()
但是, 有一些需要注意的地方.
当我们修改info新增一个字段赋值的时候, 再次读取并未生效, 是什么原因呢?
而修改info时,是在原有值的基础上做 set 操作,它的内存地址并没有变。
所以可变对象在本地进行修改,shelve 默认是不会记录的,除非创建新的对象,并把原有的对象给替换掉。
所以, sh['info']['name3'] = 'name3'
操作时, 并没有使结果生效. 如果我想得到可以直接修改的结果要如何操作呢?
一种方法是把对象整体换掉。
另一种, 在打开文件的时候,多指定一个参数 writeback
, 当指定 writeback=True
的时候,shelve 会将读取的对象都放到一个内存缓存当中。
当然也可以使用diskcache
库, 去操作, 简单一点的dbm
或者shelve
就可以满足我们的需求.
同时, shelve
并不是实时同步的, 当我在两个文件同时操作一个变量, 并不是完全一样的.
3 diskcache
diskcache
是一个 Python 的第三方库,用于在磁盘上缓存数据。
diskcache
具有如下特点:
-
持久性存储: 数据被永久性地存储在磁盘上. -
自动过期: 可以设置变量的过期时间,使得缓存中的数据在一定时间后自动过期,避免缓存数据过时而不被清理的问题, 或者在一些特殊的应用场景中可以用得到。 -
线程安全: 提供了线程安全的缓存操作,可以在多线程环境下安全地使用。 -
自动序列化: 能够自动将 Python 对象序列化为字节流并存储在磁盘上,也能够将字节流反序列化为 Python 对象。 -
易于使用: 操作简单, 提供了简单易用的 API,方便存储、获取、删除等操作。 -
内存友好: 虽然数据存储在磁盘上,但它也会使用内存来缓存最频繁访问的数据,提高访问速度。
安装
pip install diskcache
使用
设置缓存的目录, 目录不存在则创建.
import diskcache as dc
cache = dc.Cache("E:/temp/python_cache")
-
设置值
# 存储数据到缓存
cache.set("name", "orange")
# 存储复杂类型数据
cache.set("hobby", ['sing', 'dance', 'rap', 'basketball'])
-
设置带有过期时间的值
这也是diskcache
的一个特色, 可以让我们在不使用redis
服务的时候, 实现过期变量的操作.
比如, 缓存将在60秒后过期:
# 设置带有过期时间的数据
cache.set("deadline", "value", expire=60)
-
获取值
如果值不存在, 返回None, 当然, 也可以像字典一样, 设置一个不存在时返回的默认值.
# 从缓存中获取数据
cache.get("name")
# 返回默认值
default_value = cache.get("age", default="18")
-
检查键是否存在
# 检查键是否存在于缓存中
if "key" in cache:
print("Key exists in cache")
-
关闭缓存
# 关闭缓存
cache.close()
4 关于
以上都是通过python进行kv型数据持久化存储的方式, 每种方式应用的场景, 通常是不一样的, 我们可以根据我们不同的项目环境使用适合的数据库存储.
当然, 有必要, 也可以上redis等数据库.
欢迎关注我的微信公众号
原文始发于微信公众号(其之):python 持久化键值存储数据库
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/204899.html