Skip to main content

AsyncIO-vs-Sync-In-SessionDB

1. Core Concept

Synchronous SQLAlchemy (classic):

  • Operations block the Python thread until they complete.
  • Typical usage:
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base

Base = declarative_base()
engine = create_engine("sqlite:///test.db")
Session = sessionmaker(bind=engine)

class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String)

# Sync usage
with Session() as session:
user = session.query(User).filter_by(name="Alice").first()
print(user.id)

Asynchronous SQLAlchemy (asyncio):

  • Uses async/await, so your code doesn’t block the event loop while waiting for the database.
  • Requires an async-compatible database driver, like asyncpg for PostgreSQL or aiosqlite for SQLite.
  • Typical usage:
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, declarative_base
import asyncio

Base = declarative_base()
engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/db")
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

async def get_user():
async with AsyncSessionLocal() as session:
result = await session.execute(
"SELECT * FROM users WHERE name=:name", {"name": "Alice"}
)
user = result.fetchone()
print(user)

asyncio.run(get_user())

2. Key Differences

AspectSynchronousAsynchronous
ExecutionBlocks thread until query finishesNon-blocking, allows other coroutines to run while waiting
DriverStandard DB drivers (psycopg2, pymysql, sqlite3)Async drivers (asyncpg, aiosqlite, aiomysql)
SessionSessionAsyncSession
Query ExecutionDirect function calls: session.query().all()await session.execute()
Enginecreate_engine()create_async_engine()
Transactionswith session.begin(): ...async with session.begin(): ...
PerformanceGood for single-threaded or blocking appsBetter for high-concurrency async apps (web servers, async tasks)
ORM SupportFull ORMFull ORM, but you must await query results

3. Important Notes

  1. Async is not faster for a single query: It mainly helps if your app is doing many concurrent DB operations, like a web server handling hundreds of requests simultaneously.
  2. Mixing sync and async sessions is tricky: You should generally stick to one pattern in a given context.
  3. Some SQLAlchemy features are slightly different in async mode:
    • session.execute() returns a Result object; you usually use .fetchone(), .fetchall(), or .scalars().
    • Lazy loading of relationships is async too (await user.addresses).