import os from sqlmodel import SQLModel # We used the SQLAlchemy constructs -- e.g., create_async_engine and AsyncSession # -- since SQLModel 0.0.4 does not have wrappers for them as of writing. from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine from sqlalchemy.orm import sessionmaker DATABASE_URL = os.environ.get("DATABASE_URL") # The major differences between SQLModel's create_engine and SQLAlchemy's # version is that the SQLModel version adds type annotations (for editor support) # and enables the SQLAlchemy "2.0" style of engines and connections. # We need the 2.0 style for async support. # engine = create_engine(DATABASE_URL, echo=True) engine = create_async_engine(DATABASE_URL, echo=True, future=True) # Will want a "debug mode where it doesn't echo for prod async def init_db(): """ Our new Async init_db was def init_db(): SQLModel.metadata.create_all(engine) metadata.create_all doesn't execute asynchronously, so we used run_sync to execute it synchronously within the async function. """ async with engine.begin() as conn: # await conn.run_sync(SQLModel.metadata.drop_all) await conn.run_sync(SQLModel.metadata.create_all) async def get_session() -> AsyncSession: """ Our new async get_session Was def get_session(): with Session(engine) as session: yield session We disabled expire on commit behavior by passing in expire_on_commit=False. I believe this is how flask-sqlalchemy also works """ async_session = sessionmaker( engine, class_=AsyncSession, expire_on_commit=False ) async with async_session() as session: yield session