python-asyncio - 将 PonyOrm 与 FastApi 一起使用的正确方法是什么?
问题描述
对于个人项目,我将 PonyOrm 与 FastApi 一起使用;有没有一种经典的方法可以在端点的整个异步生命周期调用中保持 db_session ?
PonyOrm 的文档中谈到了使用装饰器和产量;但它对我不起作用,所以在查看了其他 Github 项目之后,我发现这个解决方法工作正常。
但我真的不知道幕后发生了什么,以及为什么 Pony 的文档对异步主题不准确。
def _enter_session():
session = db_session(sql_debug=True)
Request.pony_session = session
session.__enter__()
def _exit_session():
session = getattr(Request, 'pony_session', None)
if session is not None:
session.__exit__()
@app.middleware("http")
async def add_pony(request: Request, call_next):
_enter_session()
response = await call_next(request)
_exit_session()
return response
然后在依赖项中,例如:
async def current_user(
username: str = Depends(current_user_from_token)) -> User:
with Request.pony_session:
# db actions
在端点调用中:
@router.post("/token", response_model=Token)
async def login_for_access_token(
request: Request,
user_agent: Optional[str] = Header(None),
form_data: OAuth2PasswordRequestForm = Depends()):
status: bool = authenticate_user(
form_data.username,
form_data.password,
request.client.host,
user_agent)
@db_session
def authenticate_user(
username: str,
password: str,
client_ip: str = 'Undefined',
client_app: str = 'Undefined'):
user: User = User.get(email=username)
如果你们有更好的方法或好的解释,我很想听听:)
解决方案
我有点像 PonyORM 开发人员和 FastAPI 用户。
async 和 Pony 的问题在于 Pony 使用我们理解的原子事务。此外,如果上下文将切换到另一个协程,我们还使用可以在另一个会话中使用的线程本地缓存。我同意我们应该在文档中添加有关它的信息。
为确保一切正常,您应该将其db_session
用作上下文管理器,并确保在此代码块中没有异步调用。
如果您的端点不是异步的,您也可以db_session
为它们使用装饰器。
在 Pony 中,我们同意在某些情况下使用ContextVar
代替Local
应该会有所帮助。
一句话的答案是:使用小的短期会话,不要用异步中断它们。
推荐阅读
- c++ - 从具有指向 char 数组的指针的数组中为 String 赋值
- ansible - 使用 Ansible playbook 时出错。错误消息:“msg”:“此模块需要 boto”
- xml - 从 Biztalk 可视化地图中的单个输入节点的范围创建多个输出节点
- hyperledger-fabric - Hyperledger Fabric:使用 memberOnlyRead 功能查询私有数据
- python - 排除交互项目并返回前 N 个建议的包?
- html - 如何向上移动各种大小的“单元格”?
- python - 从两个不同的 BeautifulSoap 输出打印 URL
- sharepoint-online - 如何让我的 sharepoint 365 母版页和页面布局显示在我的 Intranet 站点上?
- javascript - 源文本字段的 Nativescript RadDataForm 值
- c# - 如何使用 C# 在 Sql-Server 中插入视频?