Python实现键值对持久化与超时时间功能
原创作者: 风吹蛋生丶
前言
当前python需求:
- 实现类似redis的键值对持久化
- 实现类似redis的键值对超时时间功能
- 通过API接口调用 (该功能忽略,可使用Django、Flask、Fastapi实现)
当前部署一个redis就可以实现,但需求方不想再部署多一个服务维护
1. 实现类似redis的键值对持久化
当前选取
configparser
模块存放键值对
pip install configparser
数据文件
1.ini
记录了
- key 键
- value 值
- ttl 超时时间 秒
- datetime 创建时间 2020-12-09 10:10:56
[key1]
values=aaa
ttl=60
datetime=2020-12-09 10:10:56
[key2]
values=bbb
ttl=60
datetime=2020-12-09 10:10:56
- 定义一个文本文件
1.ini
,如不在同个目录 请写绝对路径 - 判断key是否存在,存在则将替换掉原有的值,不存在则在文本文件中新增值
import datetime
import configparser
# 如不在同个目录 请写绝对路径
filename = '1.ini'
def set_values(key, values)
# 当前时间并格式化
date_now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 判断key是否存在
if config.has_section(key):
config.set(key, "values", values)
config.set(key, "ttl", str(ttl))
config.set(key, "datetime", date_now)
config.write(open(filename, 'w'))
else:
config[key] = {
"values": values,
"ttl": ttl,
"datetime": date_now
}
with open(filename, "w") as fs:
config.write(fs)
return "True"
2. 实现类似redis的键值对超时时间功能
- 当在获取键值对的时候,判断是否存在key值,存在则获取,不存在返回"False"
- 抓取键值对创建时间datetime和超时时间ttl, 将两值格式化后相加result
- 将result与当前时间date_now进行判断,当result小于等于date_now对键值对进行删除并返回"Flase",相反则返回键值对
def get_values(key)
# 判断key是否存在
if config.has_section(key):
datetime_values = config.get(key, "datetime")
ttl_values = config.get(key, "ttl")
# 获取文件对应key的时间日期和ttl, 两者相加
result = datetime.datetime.strptime(datetime_values, "%Y-%m-%d %H:%M:%S") + datetime.timedelta(seconds=int(ttl_values))
date_now = datetime.datetime.now()
if result <= date_now:
# ttl超时则删除对应键值
config.remove_section(key)
config.write(open(filename, 'w'))
return "False"
else:
return config.get(key, "values")
else:
return "False"
3. 通过API接口调用
安装所需模块
pip install fastapi
pip install uvicorn
main.py
# 当前需求为
# http://127.0.0.1/setKeyValues?key=hello&values=world&ttl=60
# 设置键值对和超时时间,当前需求完全可以搭配redis使用, 但需求人想将数据保存至文本,不新增新的服务
# http://127.0.0.1/getKeyValues?key=hello
# 获取键值对
# python运行
# uvicorn main:app --host 192.168.45.50 --reload
from fastapi import FastAPI
import datetime
import configparser
app = FastAPI()
filename = '1.ini'
config = configparser.ConfigParser()
config.read(filename)
@app.get("/setKeyValues")
async def set_values(key: str, values: str, ttl: int):
# 当前时间并格式化
date_now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 判断key是否存在
if config.has_section(key):
config.set(key, "values", values)
config.set(key, "ttl", str(ttl))
config.set(key, "datetime", date_now)
config.write(open(filename, 'w'))
else:
config[key] = {
"values": values,
"ttl": ttl,
"datetime": date_now
}
with open(filename, "w") as fs:
config.write(fs)
@app.get("/getKeyValues")
async def get_values(key: str):
# 判断key是否存在
if config.has_section(key):
datetime_values = config.get(key, "datetime")
ttl_values = config.get(key, "ttl")
# 获取文件对应key的时间日期和ttl, 两者相加
result = datetime.datetime.strptime(datetime_values, "%Y-%m-%d %H:%M:%S") + datetime.timedelta(seconds=int(ttl_values))
date_now = datetime.datetime.now()
if result <= date_now:
# ttl超时则删除对应键值
config.remove_section(key)
config.write(open(filename, 'w'))
return "False"
else:
return config.get(key, "values")
else:
return "False"
运行命令(可嵌入到代码中)
$ uvicorn main:app --host 192.168.45.50 --reload
INFO: Uvicorn running on http://192.168.45.50:8000 (Press CTRL+C to quit)
INFO: Started reloader process [88249] using statreload
INFO: Started server process [88251]
INFO: Waiting for application startup.
INFO: Application startup complete.
新增键值对
key: hello-1 value: world1 ttl(超时时间): 60s
key: hello-2 value: world2 ttl(超时时间): 120s
$ curl "http://192.168.45.50:8000/setKeyValues?key=hello-1&values=world1&ttl=60"
$ curl "http://192.168.45.50:8000/setKeyValues?key=hello-2&values=world2&ttl=120"
$ cat 1.ini
[hello-1]
values = world1
ttl = 60
datetime = 2021-03-01 11:28:47
[hello-2]
values = world2
ttl = 120
datetime = 2021-03-01 11:28:51
查询键值对
$ curl "http://192.168.45.50:8000/getKeyValues?key=hello-1"
# 当键值对并未超时的时候,返回
"world1"
# 当键值对超时后,返回
"False"
如有疑问,可留下评论