Python实现键值对持久化与超时时间功能

原创作者: 风吹蛋生丶

前言

当前python需求:

  1. 实现类似redis的键值对持久化
  2. 实现类似redis的键值对超时时间功能
  3. 通过API接口调用 (该功能忽略,可使用Django、Flask、Fastapi实现)

当前部署一个redis就可以实现,但需求方不想再部署多一个服务维护

1. 实现类似redis的键值对持久化

当前选取configparser模块存放键值对

pip install configparser

数据文件1.ini记录了

  1. key 键
  2. value 值
  3. ttl 超时时间 秒
  4. 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. 定义一个文本文件1.ini,如不在同个目录 请写绝对路径
  2. 判断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的键值对超时时间功能

  1. 当在获取键值对的时候,判断是否存在key值,存在则获取,不存在返回"False"
  2. 抓取键值对创建时间datetime和超时时间ttl, 将两值格式化后相加result
  3. 将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"

如有疑问,可留下评论

posted @ 2020-12-09 10:37  风吹蛋生丶  阅读(90)  评论(0编辑  收藏  举报