如何将 umongo 的对象文档模型与主 Web 应用程序分开,或者如何避免在定义文档模型的地方调用 @instance.register?

How to separate umongo's object document models from the main web app or how to avoid calling @instance.register where document models are defined?

在使用 Flask 或 FastAPI 创建 Web 应用程序时,会有一个 main.py 文件,它基本上实例化并运行所有内容。我认为这也是数据库连接和初始化的正确位置。所以理想情况下,我想要一个单独的 model.py 文件,基本上只有对象文档映射定义,没有别的。

是否可以在 umongo 中做类似的事情?

我的意思是我们需要在每个对象文档映射 class 上方调用 @instance.register。但是如果它在一个单独的文件中并且数据库没有在那里初始化,那么在那个文件中就没有实例。该实例将在 main.py 文件中声明。

例如,当您使用 Tortoise 时,它​​允许您将整个 model.py 文件作为模块传递,并使用 FastAPI 注册它,如下所示 -

register_tortoise(
    app,
    db_url=os.environ.get("DATABASE_URL"),
    modules={"models": ["models.model"]}, #model -> model.py which has all the class definitions
    generate_schemas=True
)

对于演示,您可以将以下内容作为 model.py 文件内容 -

from umongo import Document
from umongo.fields import StringField, URLField, DateTimeField
from datetime import datetime

class WebData(Document):
    url = URLField()
    summary = StringField()
    created_at = DateTimeField(missing=datetime.now)

    def __str__(self):
        return self.url

以及以下使用 FastAPI 的 main.py 文件 -

from fastapi import FastAPI
from pymongo import MongoClient
from umongo import Instance

#db = MongoClient().test
#instance = Instance(db)

app = FastAPI()

@app.get('/ping')
async def pong():
    return {'ping': 'pong'}


if __name__ == "__main__":
    import uvicorn
    uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)

您可以在导入时实例化实例,但在应用程序初始化时将数据库连接传递给它。

common.py

from umongo.frameworks import PyMongoInstance


instance = PyMongoInstance()

model.py

from umongo import Document

from .common import instance


@instance.register
class MyDocument(Document)

init.py

from .common import .instance
import .model


def create_app():
    database = MongoClient().test
    instance.init(database)
    ...

(注意:在 umongo 3 beta 中,instance.init 被重命名为 instance.set_db。)