只需格式化 FastApi 端点返回的 SQLAlchemy 模型

Posted

技术标签:

【中文标题】只需格式化 FastApi 端点返回的 SQLAlchemy 模型【英文标题】:Simply format SQLAlchemy models returned by FastApi endpoint 【发布时间】:2021-12-30 07:49:54 【问题描述】:

假设我有一个简单的 SQLAlchemy 类和一个简单的 Flask o FastAPI 实现,如下所示:

from sqlalchemy.ext.declarative import declarative_base
from pydantic import BaseModel
Base = declarative_base()

class A(Base):
    __tablename__ = 'as'
    my_id = Column(String)

class AModel(BaseModel):
    myId:str = None

还有一个像这样的简单端点:

@app_router.get('/a')
def get_all_a(session:Session = Depends(get_session)):
    return session.query(A).all()

我怎样才能确保这个端点的返回列表在 camelCase 中产生如下:

['myId': 'id1','myId': 'id2', ...]

注意:我的应用程序相当复杂,因为我也实现了分页,并且一些后处理需要更多的操作,而不仅仅是将蛇形大小写转换为驼峰大小写,因此最简单的解决方案是最好的。

我尝试过重写 dict() 方法和类似的东西,但没有成功,根本无法理解 FastAPI 如何处理结果以获取 JSON。

【问题讨论】:

这个 Stack OV 问题可以帮助你 Convert data keys between camelcase & snakecase,同时参考 marshmallow 官方文档也很有用 marshmallow - docs 【参考方案1】:

需要更多的只是从蛇形大小写到骆驼大小写的转换

好吧,如果你不使用 response_model 你没有很多选择。

解决方案是通过从蛇形大小写转换为骆驼大小写来返回您的 dict。您有递归执行此操作的函数。

为什么它是最好的解决方案?

使用正则表达式它超级快,比任何将 dict 转换为 obj 的库(如 pydantic)都快

如果您绝对不想这样做,那么您唯一的解决方案是使用 pydantic 模型、attrs 或数据类,并将您的 db 查询输出转换为带有 camelCase 变量名称(脏)的模型类型之一。

由于您使用的是 fastapi,因此您应该使用它的所有功能。

我建议这样做:

from typing import List

from sqlalchemy.ext.declarative import declarative_base
from pydantic import BaseModel, Field
from pydantic import parse_obj_as
Base = declarative_base()

class A(Base):
    __tablename__ = 'as'
    my_id = Column(String)

class AModel(BaseModel):
    myId: str = Field(alias="my_id", default=None)

@app_router.get('/a', response_model=List[AModel])
def get_all_a(session:Session = Depends(get_session)):
    return parse_obj_as(List[AModel], session.query(A).all())

请记住,在 CamelCase 中使用类变量不是一个好习惯。

黄金答案是不返回骆驼而是蛇,如果需要,让您的客户完成转换工作。

【讨论】:

在这一点上,我认为解决方案的优势可能是pydantic Docs - Alias Generator @Franco alias_generator 的问题是你不能用它们的snake语法初始化字段,我们在这里需要它,因为de db输出是snake。要使用它,我们需要从蛇转换为骆驼,因此需要解决 2 倍的初始问题。 最后我使用“同义词”sqlalchemy.orm import synonym 列解决了这个主题,但我仍然认为这个迷宫 ja 中还有另一扇门。

以上是关于只需格式化 FastApi 端点返回的 SQLAlchemy 模型的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 FastAPI 返回 HTMLResponse

使用 curl 将文件上传到 FastAPI 端点 - 307 临时重定向

覆盖 fastAPI 的 HTTPException 响应体

如何在单独的文件中使用 FastAPI Depends 的端点/路由?

FastAPI/Pydantic 接受任意发布请求正文?

FastAPI中音频流的Websockets桥接器