Right way to connect to mysql use connection pool in async falcon app #1981
-
In sync falcon app, I think i could write a something like def create_pool():
pool = create_mysql_pool
return pool
pool = create_pool() Then other modules could get connection from pool instead of connecting to db and close it for every request. class AsyncMysqlMiddleware:
async def process_request(self, req, resp):
req.context.conn = await aiomysql.connect(**db)
async def process_response(self, req, resp, *args):
await req.context.conn.close() |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
Hi @icebearrrr! With the above disclaimer in mind, in ASGI, you can make use of startup and shutdown events, that are easy to implement with Falcon middleware. You can put So we could create an import logging
import aiomysql
import falcon.asgi
# NOTE: Useful since ASGI doesn't otherwise have anything like wsgierrors
logging.basicConfig(
format='%(asctime)s [%(levelname)s] %(message)s', level=logging.INFO)
class AsyncMysqlMiddleware:
def __init__(self):
self._pool = None
async def process_startup(self, scope, event):
self._pool = await aiomysql.create_pool(
host='localhost', port=3306, user='...', password='...',
db='test')
async def process_request(self, req, resp):
req.context.pool = self._pool
try:
req.context.conn = await self._pool.acquire()
except Exception:
req.context.conn = None
raise
async def process_response(self, req, resp, resource, req_succeeded):
if req.context.conn:
self._pool.release(req.context.conn)
class Items:
async def on_get(self, req, resp):
cur = await req.context.conn.cursor()
await cur.execute('SELECT value FROM numbers')
rows = await cur.fetchall()
await cur.close()
resp.media = [row[0] for row in rows]
async def on_get_with_pool(self, req, resp):
async with req.context.pool.acquire() as conn:
cur = await conn.cursor()
await cur.execute('SELECT value FROM numbers')
rows = await cur.fetchall()
await cur.close()
resp.media = [row[0] for row in rows]
app = falcon.asgi.App(middleware=[AsyncMysqlMiddleware()])
app.add_route('/items', Items())
app.add_route('/items2', Items(), suffix='with_pool') |
Beta Was this translation helpful? Give feedback.
-
Thanks to @CaselIT, this has now been added to our FAQ: How do I manage my database connections with ASGI? w00t! |
Beta Was this translation helpful? Give feedback.
Hi @icebearrrr!
I've never used
aiomysql
, so take this with a grain of salt, as I don't know what the "right" way to work with it is.With the above disclaimer in mind, in ASGI, you can make use of startup and shutdown events, that are easy to implement with Falcon middleware. You can put
async
initialization code into aprocess_startup(...)
method, as also showcased in our ASGI tutorial.So we could create an
aiomysql
pool, and then either useprocess_request
andprocess_response
to automatically draw connections from pool and store them inreq.context
, or use the pool directly in a responder. The following works for me with both approaches: