个人总结
command.py
file.py
time.py
excel.py
with 的原理和用法
subprocess 模块
cline 提示词
PathLike
pathlib
peewee
生成随机ID
FastApi 使用 peewee
http connect
Dataframe Protocol
pyarrow
overload 函数重载
1111
peewee 线程安全
Python 日志模块
rabbitmq 问答
多进程 daemon 参数
记录异常
dict.py
多进程
忽略异常
timer.py
Ctrl+C 退出while
发布pip包
Bolo组件
迭代器与生成器
dataclass
单例模式(二)
单例模式(一)
errors.py
enum.py
每日学习
本文档使用 MrDoc 发布
-
+
首页
FastApi 使用 peewee
### 问题与解决方案 Peewee不能直接在异步框架中使用,因为它严重依赖老版本Python的 `threading.local` 对象,而这个类型的对象与新的异步特性并不兼容。 > 老版本的Python中有一种魔法变量:`threading.local`,它可以让每个线程保存和获取到自己的数据,不同的线程互不干扰。在老的框架中,每个请求都是一个单独的线程,使用它,可以保证每个请求都有自己的数据库连接对象。但是FastApi使用了新的异步特性,可以在一个线程中处理多个请求,因此该魔法变量已经不再适用。 在Python3.7及以上版本,提供了新的库 `contextvars`用来取代`threading.local` 。 想要在FastApi中使用peewee,需要改写peewee的一些内容: ``` from contextvars import ContextVar import peewee DATABASE_NAME = "test.db" db_state_default = {"closed": None, "conn": None, "ctx": None, "transactions": None} db_state = ContextVar("db_state", default=db_state_default.copy()) class PeeweeConnectionState(peewee._ConnectionState): def __init__(self, **kwargs): super().__setattr__("_state", db_state) super().__init__(**kwargs) def __setattr__(self, name, value): self._state.get()[name] = value def __getattr__(self, name): return self._state.get()[name] db = peewee.SqliteDatabase(DATABASE_NAME, check_same_thread=False) db._state = PeeweeConnectionState() ``` 使用示例: ``` import time from typing import List from fastapi import Depends, FastAPI, HTTPException from . import crud, database, models, schemas from .database import db_state_default database.db.connect() database.db.create_tables([models.User, models.Item]) database.db.close() app = FastAPI() sleep_time = 10 async def reset_db_state(): database.db._state._state.set(db_state_default.copy()) database.db._state.reset() def get_db(db_state=Depends(reset_db_state)): try: database.db.connect() yield finally: if not database.db.is_closed(): database.db.close() @app.post("/users/", response_model=schemas.User, dependencies=[Depends(get_db)]) def create_user(user: schemas.UserCreate): db_user = crud.get_user_by_email(email=user.email) if db_user: raise HTTPException(status_code=400, detail="Email already registered") return crud.create_user(user=user) @app.get("/users/", response_model=List[schemas.User], dependencies=[Depends(get_db)]) def read_users(skip: int = 0, limit: int = 100): users = crud.get_users(skip=skip, limit=limit) return users @app.get( "/users/{user_id}", response_model=schemas.User, dependencies=[Depends(get_db)] ) def read_user(user_id: int): db_user = crud.get_user(user_id=user_id) if db_user is None: raise HTTPException(status_code=404, detail="User not found") return db_user @app.post( "/users/{user_id}/items/", response_model=schemas.Item, dependencies=[Depends(get_db)], ) def create_item_for_user(user_id: int, item: schemas.ItemCreate): return crud.create_user_item(item=item, user_id=user_id) @app.get("/items/", response_model=List[schemas.Item], dependencies=[Depends(get_db)]) def read_items(skip: int = 0, limit: int = 100): items = crud.get_items(skip=skip, limit=limit) return items @app.get( "/slowusers/", response_model=List[schemas.User], dependencies=[Depends(get_db)] ) def read_slow_users(skip: int = 0, limit: int = 100): global sleep_time sleep_time = max(0, sleep_time - 1) time.sleep(sleep_time) # Fake long processing request users = crud.get_users(skip=skip, limit=limit) return users ``` ### 参考文档 > [【FastApi官方文档】SQL (Relational) Databases with Peewee](https://fastapi.tiangolo.com/how-to/sql-databases-peewee/)
gaojian
2023年11月21日 11:54
分享文档
收藏文档
上一篇
下一篇
微信扫一扫
复制链接
手机扫一扫进行分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码