Open pylixm opened 3 years ago
例如用postgresql 需要配合异步驱动才行,参考sqlalchemy手册的asyncio support
I think that if you are creating your own engine, you will need to give the middleware the actual async engine object rather than the function to create the engine. Maybe this code will help you (I havent run it but hopefully it'll point you in the right direction).
from fastapi import FastAPI
from fastapi_sqlalchemy import DBSessionMiddleware # middleware helper
from fastapi_sqlalchemy import db # an object to provide global access to a database session
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from models.user import User
app = FastAPI()
# async engine object to give to the middleware
engine = create_async_engine('sqlite://')
app.add_middleware(DBSessionMiddleware,
custom_engine=engine,
session_args={
'expire_on_commit': False,
'class_': AsyncSession
})
# once the middleware is applied, any route can then access the database session
# from the global ``db``
@app.get("/users")
async def get_users():
users = await db.session.query(User).all()
return users
if __name__ == '__main__':
import uvicorn
uvicorn.run(app=app, host="127.0.0.1", port=8001, log_level="debug")
Is that enough or does this library also need to add asynchronous context manager support to DBSession
? For example:
class DBSession(metaclass=DBSessionMeta):
def __init__(self, session_args: Dict = None, commit_on_exit: bool = False):
self.token = None
self.session_args = session_args or {}
self.commit_on_exit = commit_on_exit
async def __aenter__(self):
if not isinstance(_Session, sessionmaker):
raise SessionNotInitialisedError
self.token = _session.set(_Session(**self.session_args))
return type(self)
async def __aexit__(self, exc_type, exc_value, traceback):
sess = _session.get()
if exc_type is not None:
await sess.rollback()
if self.commit_on_exit:
await sess.commit()
await sess.close()
_session.reset(self.token)
and then tweak the dispatch
in the middleware:
async def dispatch(self, request: Request, call_next: RequestResponseEndpoint):
async with db(commit_on_exit=self.commit_on_exit):
response = await call_next(request)
return response
@pylixm https://github.com/h0rn3t/fastapi-async-sqlalchemy u can try this
@pylixm I'm late to the party: Check https://github.com/dialoguemd/fastapi-sqla/ as well. It's compatible with sqla 1.3, 1.4, 2.0 and with async support.
How does the library use asynchronous mode?
Below is the code I tried, but it not work.
Does anyone else have any ideas?