From 36dd51a0343b0500643957d82cd1013805930202 Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Thu, 10 Sep 2020 12:32:28 +0900 Subject: [PATCH 1/3] release connections of multiple dbs --- src/gino_starlette.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) 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,) From e70a749a3f031ea0bb0e48343f50e1f269a200f2 Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Thu, 10 Sep 2020 12:36:04 +0900 Subject: [PATCH 2/3] update doc --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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']] ``` From 75bbc9b34628ba04639b0f386b7670deff61c7b2 Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Thu, 10 Sep 2020 12:37:26 +0900 Subject: [PATCH 3/3] fix test --- tests/conftest.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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)