MongoDb与FastAPI的结合

18

我正在尝试使用 FastAPI,并希望将其连接到MongoDB数据库。然而,我不确定在motor和mongoengine之间选择哪个ODM。此外,在NoSQL示例(此处)中,他们创建了一个新的bucket,并且每次使用时都调用了连接到数据库的代码。然而,motor和mongoengine似乎都更喜欢全局连接。那么连接MongoDB的好方法是什么?

3个回答

34

我相信你已经在Github上的Fastapi项目的问题论坛中得到了你的答案:Issue 452 (closed)。但为了以后参考,我会在这里总结解决方案:

简而言之,你可以使用motormongoengine,Fastapi都支持,并且你可以重复使用一个全局客户端对象,该对象启动并随应用程序进程结束。

一些上下文细节(希望)澄清这些技术及其关系:

Python的官方MongoDB驱动程序是pymongo。在幕后,MongoEngine和Motor都使用Pymongo。 Pymongo实现了一个针对MongoDB(备件)的直接客户端,并提供了一个Python API来发出请求。

如果您愿意,您可以直接在Fastapi中使用pymongo。(在SQL方面,这相当于在Flask中直接使用psycopg2而无需通过类似SQLAlchemy的东西。)

MongoEngine是一个ODM(对象-文档映射器)。 它提供了一个Python面向对象的API,您可以在应用程序中使用它来更舒适地工作,当涉及到实际的DB请求时,MongoEngine将使用pymongo。

Motor是pymongo的封装,使其非阻塞(允许async/await)。 它使用一个事件循环,通过Tornado或asyncio。 如果您正在使用带有uvicorn的Fastapi,则uvicorn将使用uvloop实现异步功能。 简而言之,在FastAPI中使用Motor,异步应该“只是工作”。 不幸的是,Motor没有实现ODM。 在这个意义上,它更类似于pymongo。

Fastapi处理来自客户端的请求(使用Starlette),但它会让您实现自己对MongoDB的连接。 因此,您并不限于任何特定的选择,但大多数情况下都是自己操作(a la Flask)。

您可以使用FastAPI应用程序的启动/关闭钩子来启动/停止Motor/MongoEngine客户端。 由于Fastapi是单线程的,因此您不需要担心由于多进程问题而导致客户端对象不持久。

@app.on_event("startup")
async def create_db_client():
    # start client here and reuse in future requests


@app.on_event("shutdown")
async def shutdown_db_client():
    # stop your client here

可以在这里找到使用Fastapi实现电机的示例。


10

我最近创建了一个适用于FastAPI的异步Mongo ODM:ODMantic

app = FastAPI()
engine = AIOEngine()

class Tree(Model):
    """This model can be used either as a Pydantic model or 
       saved to the database"""
    name: str
    average_size: float
    discovery_year: int

@app.get("/trees/", response_model=List[Tree])
async def get_trees():
    trees = await engine.find(Tree)
    return trees

@app.put("/trees/", response_model=Tree)
async def create_tree(tree: Tree):
    await engine.save(tree)
    return tree

您可以查看FastAPI示例,以获得更详细的例子。


1

我不同意接受的答案,认为fastapi是单线程的。

据我所知,如果您使用异步函数处理请求,则fastapi只能是单线程的。因此,如果您在幕后不使用异步,则starlette应该使用来自线程池的多个线程来处理多个请求。

有关线程模型和fastapi / starlette中的异步的更多信息,请参见此介绍https://fastapi.tiangolo.com/async/

https://dev59.com/u8Pra4cB1Zd3GeqPZSAK


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接