Skip to content
tezvyn:
Menu

SQLAlchemy 2.0: Async Without Blocking the Event Loop

Source: docs.sqlalchemy.orgMediumHow cards are made

SQLAlchemy 2.0 wraps its synchronous core with an async API, letting you await database calls without blocking your app's event loop. Use it in frameworks like FastAPI.

Why it exists

Traditional Python applications often used one thread per request, where a blocking database call was acceptable. Modern asyncio frameworks like FastAPI use a single event loop to handle many concurrent requests. A synchronous database call in this model would block the entire application, so a non-blocking way to interact with the database became essential.

The mental model

SQLAlchemy's async support is not a from-scratch rewrite; it's an adapter layer over its battle-tested synchronous core. You construct queries using the same powerful ORM and Core expressions. The difference is that all operations that perform I/O—like fetching results or committing a transaction—are now awaitable methods. It lets you write async code without learning a whole new query language.

How it works

Instead of create_engine, you use create_async_engine with an async-compatible DBAPI driver (like asyncpg for PostgreSQL). You then use an async_sessionmaker to create AsyncSession objects. All I/O-bound methods on the session and result objects must be awaited: result = await session.execute(...), users = result.scalars().all(), and await session.commit(). Under the hood, SQLAlchemy manages running the synchronous driver code in a way that doesn't block the main asyncio event loop.

When to use it

Use this whenever you are building an application on an asyncio framework like FastAPI, Starlette, or Quart. It is the standard for building high-concurrency Python services that need to talk to a relational database without creating performance bottlenecks from blocked I/O.

When not to use it

If your application is purely synchronous (e.g., a simple Flask app, a command-line script, or a basic data analysis task), the async interface adds unnecessary complexity. Stick to the standard synchronous create_engine and Session. The performance benefit only materializes within an active asyncio event loop.

One canonical example

In a FastAPI app, you create a single async_sessionmaker at startup. For each incoming request, a dependency injection function yields a new AsyncSession. Your API endpoint function can then await database calls. The most common footgun is triggering implicit I/O. For example, accessing a lazy-loaded relationship like user.addresses without an explicit eager loading strategy (like selectinload) will cause a synchronous database query, blocking the event loop and defeating the entire purpose of using async.

Interview question

What is the primary reason to use SQLAlchemy 2.0's async API in an application built with an asyncio framework?

  • a.To simplify the process of writing complex SQL queries using Python objects.
  • b.To significantly reduce the execution time of individual database queries.
  • c.To prevent database I/O operations from blocking the application's single event loop.Correct
  • d.To enable SQLAlchemy to connect to a wider range of asynchronous database drivers.
Why?

The card states that a synchronous database call in an asyncio framework would "block the entire application," making the async API essential for a "non-blocking way to interact with the database." While it improves concurrency, it doesn't inherently make individual queries faster.

Just read this? Test yourself on what you have been reading.

Read the original → docs.sqlalchemy.org

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on python — each one lists the topics its interview covers.

See open roles