小记一次FastAPI使用连接池调用Redis时,切换数据库的问题
之前因为项目需要,尝试了新兴框架 FastAPI,他的很多特性十分值得称赞,比如自动文档、类型校验、速度、异步等等
但是在使用过程中遇到了切换Redis db的需求,比如验证码、用户登录信息等等的缓存需要通过db隔离,因为FastApi的异步特性,当时选用了aioredis 作为驱动,但是翻了翻文档并没有找到在创建连接池后切换数据库的方法,于是参考了Django框架的实现原理:给每一个db单独创建连接池,在使用时根据需求调用即可
于是编写代码如下:
class RedisPool:
redis_pool_dict = {}
def __await__(self):
self._create_pool()
return self._create_pool().__await__()
async def _create_pool(self):
for i in settings.REDIS_DB_LIST:
redis = await aioredis.create_redis_pool(
settings.REDIS_URL + "{db}?encoding=utf-8".format(db=i)
)
self.redis_pool_dict.update({i: redis})
return self
def select_db(self, db=52):
c = self.redis_pool_dict[db]
if not c:
raise ValueError('调用的Redis数据库未创建连接池')
return c
def close_pool(self):
for i in self.redis_pool_dict.values():
i.close()
结合框架如下:
def register_redis(app: FastAPI) -> None:
@app.on_event("startup")
async def create_redis():
app.state.redis = await RedisPool()
@app.on_event("shutdown")
async def close_redis():
app.state.redis.close_pool()
调用方法如下:
redis_client = request.app.state.redis.select_db(db=53)
rs = await redis_client.set(
key="test_key-",
value="12",
expire=60 * 60 * 4 # token过期时间为4小时
)
大概逻辑如下:
- 迭代配置文件声明的,需要使用的db列表
- 创建每个db的pool
- 使用时找到需要的拿去用即可
其他:
- 在框架启动时利用FastAPI的@app.on_event("startup")初始化连接池
- 在框架关闭时close_pool()
上面值得注意的是,因为aioredis是异步的,所以一处异步处处异步 异步类不常写,所以记录一下