diff --git a/README.md b/README.md index 90443b0..2f46476 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,17 @@ The config includes: ## Lazy Connection If `use_connection_for_request` is set to be True, then a lazy connection is available -at `request['connection']`. By default, a database connection is borrowed on the first +at `request['connections']`. By default, a database connection is borrowed on the first query, shared in the same execution context, and returned to the pool on response. If you need to release the connection early in the middle to do some long-running tasks, you can simply do this: ```python -await request['connection'].release(permanent=False) +await request['connections'][0].release(permanent=False) +``` + +Or iterate it if you have multiple databases like: + +```python +[await conn.release(permanent=False) for conn in request['connections']] ``` diff --git a/src/gino_starlette.py b/src/gino_starlette.py index 1e2365a..f068a64 100644 --- a/src/gino_starlette.py +++ b/src/gino_starlette.py @@ -74,12 +74,17 @@ async def __call__( self, scope: Scope, receive: Receive, send: Send ) -> None: if scope["type"] == "http" and self._conn_for_req: - scope["connection"] = await self.db.acquire(lazy=True) + conn = await self.db.acquire(lazy=True) + + if "connections" not in scope: + scope["connections"] = [] + scope["connections"].append(conn) + try: await self.app(scope, receive, send) finally: - conn = scope.pop("connection", None) - if conn is not None: + conns = scope.pop("connections", []) + for conn in conns: await conn.release() return @@ -123,14 +128,17 @@ class Gino(_Gino): like ``asyncpg``. Unrecognized parameters will cause exceptions. If ``use_connection_for_request`` is set to be True, then a lazy connection - is available at ``request['connection']``. By default, a database + is available in ``request['connections']``. By default, a database connection is borrowed on the first query, shared in the same execution context, and returned to the pool on response. If you need to release the connection early in the middle to do some long-running tasks, you can simply do this:: - await request['connection'].release(permanent=False) + await request['connections'][0].release(permanent=False) + + Or iterate it if you have multiple databases like: + [await conn.release(permanent=False) for conn in request['connections']] """ model_base_classes = _Gino.model_base_classes + (StarletteModelMixin,) diff --git a/tests/conftest.py b/tests/conftest.py index 8a5a4f7..e8b5802 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -176,7 +176,7 @@ class User(db.Model): @app.route("/") async def root(request): - conn = await request["connection"].get_raw_connection() + conn = await request["connections"][0].get_raw_connection() # noinspection PyProtectedMember assert ( conn._holder._max_inactive_time == _MAX_INACTIVE_CONNECTION_LIFETIME @@ -192,7 +192,7 @@ async def get_user(request): return JSONResponse((await q.gino.first_or_404()).to_dict()) elif method == "2": return JSONResponse( - (await request["connection"].first_or_404(q)).to_dict() + (await request["connections"][0].first_or_404(q)).to_dict() ) elif method == "3": return JSONResponse((await db.bind.first_or_404(q)).to_dict()) @@ -207,7 +207,7 @@ async def add_user(request): await u.query.gino.first_or_404() await db.first_or_404(u.query) await db.bind.first_or_404(u.query) - await request["connection"].first_or_404(u.query) + await request["connections"][0].first_or_404(u.query) return JSONResponse(u.to_dict()) e = await gino.create_engine(PG_URL)