为什么fastapi不返回我的mongodb对象?

问题描述 投票:0回答:3

所以我尝试在路线上提出请求:

http://127.0.0.1:8000/testadmins 具有以下功能:

@app.get("/testadmins/")
async def get_admins():
    return await get_database()

get_database() 是这样的:

async def get_database():
    uri = "(my mongo uri)"
    client = MongoClient(uri, server_api=ServerApi('1'))
    adms = client.test['admins'].find()
    print(adms)
    
    return adms

该函数应返回该集合中的所有管理员。

如果我将管理员打印到控制台,则会显示它们,但路线不会返回它们。 我收到这个错误: TypeError('vars() 参数必须具有 dict 属性')]

我尝试在各处添加 async wait,我尝试将函数包装在 fastApi 的 json_encodable() 中 但什么也没有。

如果我尝试在 Postman 中发出请求,它会返回 500(内部服务器错误)。

我该怎么办?

(更新:我认为这与日期和时间有关,因为它一次只尝试一个键多次,并且只有那些具有存储为 datetime.datetime(...) 格式的值的键不起作用。

( __v 和 _id 也不起作用,但 idk )

追溯:

Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/fastapi/encoders.py", line 235, in jsonable_encoder
    data = vars(obj)
           ^^^^^^^^^
TypeError: vars() argument must have __dict__ attribute

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 426, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 84, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/fastapi/applications.py", line 289, in __call__
    await super().__call__(scope, receive, send)
  File "/opt/homebrew/lib/python3.11/site-packages/starlette/applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/opt/homebrew/lib/python3.11/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/opt/homebrew/lib/python3.11/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/opt/homebrew/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/opt/homebrew/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/opt/homebrew/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__
    raise e
  File "/opt/homebrew/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "/opt/homebrew/lib/python3.11/site-packages/starlette/routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "/opt/homebrew/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/opt/homebrew/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
               ^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/fastapi/routing.py", line 291, in app
    content = await serialize_response(
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/fastapi/routing.py", line 179, in serialize_response
    return jsonable_encoder(response_content)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/fastapi/encoders.py", line 209, in jsonable_encoder
    jsonable_encoder(
  File "/opt/homebrew/lib/python3.11/site-packages/fastapi/encoders.py", line 238, in jsonable_encoder
    raise ValueError(errors) from e
ValueError: [TypeError("'ObjectId' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]

python mongodb rest postman fastapi
3个回答
0
投票

你应该修改

async def get_database():
    uri = "(my mongo uri)"
    client = MongoClient(uri, server_api=ServerApi('1'))
    adms = []
    cursor = client.test['admins'].find()
    for document in cursor:
        document.pop('ObjectId')
        adms.append(document)
    return adms

0
投票

**我通过以下方法解决了对象 ID 问题:**

document['_id'] = str(document['_id'])

我刚刚将其转换为字符串,现在它可以工作了。

我还删除了一些其他函数调用,添加了一些参数,无论如何,这是整个代码:

db = MongoClient(uri)

    result = []
    collection = db.test[collection_name].find()

    for document in collection:
        # Convert ObjectId to string
        document['_id'] = str(document['_id'])
        result.append(document)

    return result

0
投票

问题在于 bson.ObjectID 对象未编码。

我检查了fastapi版本0.110.0你可以明确地为特定类型添加econders。

在包含端点的模块中,假设 main.py,添加:

from bson import ObjectId
from fastapi.encoders import ENCODERS_BY_TYPE

ENCODERS_BY_TYPE[ObjectId] = str

这指定编码器将 bson.ObjectId 对象类转换为 str

每次需要对 bson.ObjectId 进行编码时,它都会自动进行编码

© www.soinside.com 2019 - 2024. All rights reserved.