Comprehensive guide to constructing ORM queries using select() statements
SQLAlchemy 2.0 introduces a unified approach to querying using the select() construct. This guide covers the core query APIs for filtering, ordering, and limiting results.
The modern SQLAlchemy ORM uses select() for all query construction, replacing the legacy Query object. The select() function creates SQL SELECT statements that work seamlessly with the ORM.
SQLAlchemy 2.0 style uses select() from sqlalchemy (or sqlalchemy.future in 1.4) instead of the legacy session.query() pattern.
from sqlalchemy import selectfrom sqlalchemy.orm import Session
2
Create a basic select statement
Construct a query by passing entity classes to select():
from models import User# Select all usersstmt = select(User)# Execute with sessionwith Session(engine) as session: users = session.scalars(stmt).all()
3
Execute and retrieve results
Use session.scalars() for ORM objects or session.execute() for rows:
# Get scalar ORM objectsusers = session.scalars(select(User)).all()# Get first resultuser = session.scalars(select(User)).first()# Get one result (raises if not exactly one)user = session.scalars(select(User)).one()
Control pagination and result set size using limit() and offset().
# Get first 10 usersstmt = select(User).limit(10)users = session.scalars(stmt).all()
Performance Consideration: Always use order_by() with limit() and offset() to ensure consistent pagination results. Without explicit ordering, result order is undefined.
Different ways to execute queries and retrieve results.
Method
Returns
Use Case
.scalars()
Scalar values
Single entity queries
.execute()
Row objects
Multi-column or mixed queries
.all()
List
Get all results
.first()
Single or None
Get first result
.one()
Single (raises if not exactly one)
Expect exactly one result
.one_or_none()
Single or None (raises if multiple)
Expect zero or one result
# Examplesstmt = select(User)# Get all users as listusers = session.scalars(stmt).all()# Get first user or Noneuser = session.scalars(stmt).first()# Expect exactly one useruser = session.scalars(stmt.where(User.id == 1)).one()# Iterate without loading all into memoryfor user in session.scalars(stmt): process(user)
Use scalars() when selecting a single entity type. Use execute() when selecting multiple columns or entities.