fastapi: 第二十九章:访问redis
一,安装用到的第三方库
$ pip install redis
说明:
redis库和aioredis库两者有什么区别?
这是一个非常经典的“历史遗留”问题。其实在今天,它们已经没有区别了,因为它们已经合并成了同一个库。
简单来说:aioredis 已经被合并到了官方的 redis 库中。
二,代码:
连接
# app/core/redislink.py
import asyncio
from contextlib import asynccontextmanager
from typing import AsyncGenerator
from fastapi import FastAPI, Depends, HTTPException
import redis.asyncio as aioredis
# 定义一个全局的 Redis 连接池变量
redis_pool: aioredis.ConnectionPool | None = None
# 1. 使用 Lifespan 管理管理 Redis 连接池的生命周期
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
global redis_pool
print("正在连接 Redis...")
# 初始化异步连接池
redis_pool = aioredis.ConnectionPool(
host="localhost",
port=6379,
db=0,
decode_responses=True # 自动将字节解码为字符串
)
yield
# 应用关闭时,优雅地关闭连接池
print("正在关闭 Redis 连接...")
await redis_pool.disconnect()
# 2. 创建一个 Dependency(依赖项),用于在接口中获取 Redis 客户端
async def get_redis() -> AsyncGenerator[aioredis.Redis, None]:
if redis_pool is None:
raise RuntimeError("Redis 连接池未初始化")
# 从连接池中获取一个连接
async with aioredis.Redis(connection_pool=redis_pool) as client:
yield client
main
# 创建FastAPI应用,并传入 lifespan
app = FastAPI(lifespan=lifespan,title="我的API项目")
调用:
# --- 3. 编写 API 接口 ---
from fastapi import HTTPException, APIRouter, Depends
import redis.asyncio as aioredis
from app.core.redislink import get_redis
router = APIRouter(prefix="/toke", tags=["token管理"])
@router.get("/set/{key}")
async def set_value(key: str, value: str, r: aioredis.Redis = Depends(get_redis)):
"""设置键值对,并设置 60 秒过期时间"""
await r.set(key, value, ex=60)
return {"status": "success", "message": f"键 '{key}' 已保存,60秒后过期"}
@router.get("/get/{key}")
async def get_value(key: str, r: aioredis.Redis = Depends(get_redis)):
"""获取键值对"""
value = await r.get(key)
if value is None:
raise HTTPException(status_code=404, detail="未找到该键或已过期")
return {"key": key, "value": value}
@router.get("/delete/{key}")
async def delete_value(key: str, r: aioredis.Redis = Depends(get_redis)):
"""删除键值对"""
result = await r.delete(key)
if result == 0:
raise HTTPException(status_code=404, detail="键不存在,无法删除")
return {"status": "success", "message": f"键 '{key}' 已删除"}
相关的说明:
💡 为什么用 lifespan?
旧版本的 FastAPI 使用 @app.on_event("startup"),但这已被官方废弃。现在的 lifespan 机制可以将启动和关闭逻辑写在同一个函数里(通过 yield 分割),更加直观且安全。
💡 为什么要用 ConnectionPool(连接池)?
频繁地创建和销毁 Redis 连接非常消耗性能。通过连接池,多个请求可以复用已有的连接。
💡 decode_responses=True 的作用
如果不加这个参数,Redis 返回的数据默认是 Python 的 bytes 类型(例如 b"value")。加上后,连接器会自动帮你转换成 str(例如 "value"),省去了手动 .decode('utf-8') 的麻烦。
三,测试效果 :


浙公网安备 33010602011771号