databases icon indicating copy to clipboard operation
databases copied to clipboard

Postponed configuration of database

Open artslob opened this issue 5 years ago • 0 comments

Session from sqlalchemy allows postponed configuration:

SessionFactory = sessionmaker()
SessionFactory.configure(bind=create_engine('sqlite://'))

session_instance = SessionFactory()

Maybe Database should be also has configure method? This allows to create Database object at import time but set parameters for connection (url, pool size, etc) at runtime.

Right now I use FastAPI framework with factory pattern:

def create_app() -> FastAPI:
    app = FastAPI()

    cfg = app.state.cfg = config.parse_config()

    database = app.state.database = create_database(cfg.database)

This way I have database instance when handling requests. But I cannot set decorators on function at import time like this because I dont have database instance at import time because I parse config at runtime:

@database.transaction()  # cannot do this
async def create_users(request):
    ...

So possible API can be look like this:

database = Database()


def create_app() -> FastAPI:
    app = FastAPI()

    cfg = app.state.cfg = config.parse_config()

    database.initialize(url=cfg.url)

    @app.on_event("startup")
    async def startup():
        await database.connect()

    app.include_route(create_users)


@database.transaction()
async def create_users(request):
    database.execute(create_query)
    return database.fetch_one(query)

Also should note, that configure method should allow multiple calls, so in tests fixture with function scope can recreate ASGI app multiple times (call factory method), which in turn calls configure.

artslob avatar Oct 07 '20 09:10 artslob