http://127.0.0.1:8000/testadmins 具有以下功能:
@app.get("/testadmins/")
async def get_admins():
return await 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')]
你应该修改
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
**我通过以下方法解决了对象 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
问题在于 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 进行编码时,它都会自动进行编码