FastAPI SQLAlchemy 返回数据类似字典。

huangapple go评论59阅读模式
英文:

FastAPI SQLAlchemy return data like dictionary

问题

学习FastAPI和SQLAlchemy的视频教程。在视频代码中工作正常。

教程中的代码:

@router.get("/")
async def get_specific_operations(operation_type: str, session: AsyncSession = Depends(get_async_session)):
    query = select(operation).where(operation.c.type == operation_type)
    result = await session.execute(query)
    return result.all()

当我使用这段代码时,出现错误“无法将字典更新序列元素 #0 转换为序列”。

我尝试过:

return result.scalars().all()

但我只得到id号码,没有其他字符串数据。

使用链式调用:

@router.get("/")
async def get_specific_operations(operation_type: str, session: AsyncSession = Depends(get_async_session)):
    query = select(operation).where(operation.c.type == operation_type)
    result = await session.execute(query)
    result = list(chain(*result))
    return result

我得到了正确的结果,但没有列标题。用户不能完全理解这些信息。

我想要的/我得到的(就像视频中的一样):

         /  [
[        /   {
 4       /    id: 4
 name    /    username: name
 25,     /    age: 25
 7       /   },
 name2   /   {
 31      /    id: 7
]        /    username: name2
         /    age:31
         /   }
         /  ]

我如何能够从数据库的字符串中获取完整信息和列名?我需要一个字典列表,我认为。

英文:

Learning FastAPI and SQLAlchemy with video tutorial. In video code working correct.

Code from tutorial:

@router.get("/")
async def get_specific_operations(operation_type: str, session: AsyncSession = Depends(get_async_session)):
    query = select(operation).where(operation.c.type == operation_type)
    result = await session.execute(query)
    return result.all()

When I using this code, I have error "Cannot convert dictionary update sequence element #0 to a sequence"

I tried:

return result.scalars().all()

But I get only id numbers, without another data from strings.

With chain:

@router.get("/")
async def get_specific_operations(operation_type: str, session: AsyncSession = Depends(get_async_session)):
    query = select(operation).where(operation.c.type == operation_type)
    result = await session.execute(query)
    result = list(chain(*result))
    return result

I get correct results, but without column titles. This information is not fully understood by the user.

I get / I need (this like in video):

         /  [
[        /   {
 4       /    id: 4
 name    /    username: name
 25,     /    age: 25
 7       /   },
 name2   /   {
 31      /    id: 7
]        /    username: name2
         /    age:31
         /   }
         /  ]

How I can get full information from string of DB with column names? I need a list of dictionaries, I think.

答案1

得分: 1

我找到了一个帮助我的解决方案。只需更改 "return":

@router.get("/")
async def get_specific_operations(operation_type: str, session: AsyncSession = Depends(get_async_session)):
    query = select(operation).where(operation.c.type == operation_type)
    result = await session.execute(query)
    return [dict(r._mapping) for r in result]
英文:

I found a solution that helped me. Just changed "return":

@router.get("/")
async def get_specific_operations(operation_type: str, session: AsyncSession = Depends(get_async_session)):
    query = select(operation).where(operation.c.type == operation_type)
    result = await session.execute(query)
    return [dict(r._mapping) for r in result]

答案2

得分: 0

以下是翻译好的内容:

你的第一个示例无法正常工作的原因是 FastAPI 不知道如何将 SQLAlchemy 的 Row 对象(result.all() 返回的对象列表)转换。然而,在 FastAPI 中的惯用方式是为你想要的响应定义一个 Pydantic 模型,然后它将使用其 BaseModel.from_orm 方法从你的 SQLAlchemy 对象中提取数据。

这样做的额外好处是,你的 JSON 响应结构将在你的 OpenAPI 文档中正确显示。

(对于未来的读者,请注意,我在这里使用的是 FastAPI 0.99.1,它尚不支持 Pydantic 2.0,这就是为什么我仍然使用 Pydantic 1.x 的原因。)

英文:

The reason your first example doesn't work is that a FastAPI doesn't know how to convert SQLAlchemy Row objects (which is what result.all() returns a list of). However, the idiomatic way in FastAPI is to define a Pydantic model for the response you want, and then it will use its BaseModel.from_orm method to extract data from your SQLAlchemy objects.

from pydantic import BaseModel

class OperationSchema(BaseModel):
    id: int
    username: str
    age: int

    class Config:
        orm_mode = True


@router.get("/", response_model=list[OperationSchema])
async def get_specific_operations(operation_type: str, session: AsyncSession = Depends(get_async_session)):
    query = select(operation).where(operation.c.type == operation_type)
    result = await session.execute(query)
    return result.all()

This has the added advantage that the structure of your JSON response will be correct in the autoge of your OpenAPI documentation.

(For future readers, note that I'm using FastAPI 0.99.1 here, which doesn't yet support Pydantic 2.0, which is why I'm still using Pydantic 1.x)

huangapple
  • 本文由 发表于 2023年7月4日 22:01:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613427.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定