While creating a web app using Flask or FastAPI, there would be a main.py file that basically instantiates and runs everything. I think that is also the right place for the database connections and initialization. So ideally I'd like to have a separate model.py file that basically just has the object document mapping definitions and nothing else.
Is it possible to do something like that in umongo?
I mean we need to call @instance.register
above every object document map class. But if that is in a separate file and the DB is not initialized there, then in that file there are no instances. The instance would be declared in the main.py file.
For example, when you use Tortoise, it allows you to pass the whole model.py file as a module and register it with FastAPI like the following -
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
)
For demo, you can have the following as model.py
file contents -
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
And the following main.py file that uses FastAPI -
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)
You can instantiate the instance at import but pass it a DB connection at app init.
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)
...
(Note: in umongo 3 beta, instance.init
is renamed to instance.set_db
.)