Select
下面给你一份 SQLAlchemy 2.0 ORM select() 最清晰、最完整、最实战的教程,涵盖基础、进阶、JOIN、过滤、多表、分页、聚合、子查询、返回值处理等内容。
内容经过整理,完全适配 SQLAlchemy 2.0(sync + async 通用)。
from sqlalchemy import select
from models import User
stmt = select(User)
result = session.execute(stmt).scalars().all()
返回格式(ORM 模式)
result.scalars().all() -> list[User]
stmt = select(User.id, User.name)
rows = session.execute(stmt).all()
返回格式
[(1, "martin"), (2, "john"), ...]
stmt = select(User).where(User.status == 1)
stmt = select(User).where(
User.age > 18,
User.status == 1
)
from sqlalchemy import or_
stmt = select(User).where(
or_(User.age < 18, User.status == 0)
)
stmt = select(User).where(User.id.in_([1, 2, 3]))
stmt = select(User).where(User.name.like("%martin%"))
stmt = select(User).order_by(User.id.desc())
stmt = (
select(User)
.order_by(User.id.desc())
.limit(10)
.offset(0)
)
内连接 JOIN
stmt = (
select(User, Profile)
.join(Profile, Profile.user_id == User.id)
)
返回值示例:
[(User, Profile), (User, Profile), ...]
LEFT JOIN
stmt = (
select(User, Profile)
.outerjoin(Profile, Profile.user_id == User.id)
)
stmt = (
select(User.id, User.name, Profile.age)
.join(Profile, Profile.user_id == User.id)
)
返回格式:
[(1, "Martin", 25), ...]
stmt = select(User.name).distinct()
from sqlalchemy import func
stmt = (
select(User.status, func.count())
.group_by(User.status)
)
返回:
[(1, 10), (0, 3)]
子查询构建
subq = (
select(User.id)
.where(User.status == 1)
).subquery()
主查询使用
stmt = select(Profile).where(Profile.user_id.in_(subq))
from sqlalchemy import exists
subq = select(User.id).where(User.id == Profile.user_id)
stmt = select(Profile).where(exists(subq))
返回单个值,例如 COUNT、MAX:
count = session.execute(select(func.count()).select_from(User)).scalar()
返回 ORM 对象或单个列:
names = session.execute(select(User.name)).scalars().all()
返回 dict-like 结构:
rows = session.execute(select(User.id, User.name)).mappings().all()
返回示例:
[{'id': 1, 'name': 'martin'}]
filters = []
if status is not None:
filters.append(User.status == status)
if keyword:
filters.append(User.name.like(f"%{keyword}%"))
stmt = select(User).where(*filters)
print(stmt)
或者:
print(stmt.compile(compile_kwargs={"literal_binds": True}))
同步只需换成 async 版本:
result = await session.execute(stmt)
rows = result.scalars().all()
完整示例:
async with async_session() as session:
stmt = select(User).where(User.status == 1)
result = await session.execute(stmt)
users = result.scalars().all()
stmt = (
select(User.id, User.name, Profile.age)
.join(Profile, Profile.user_id == User.id)
.where(
User.status == 1,
User.name.like(f"%{keyword}%"),
)
.order_by(User.id.desc())
.limit(10)
.offset(0)
)
rows = session.execute(stmt).mappings().all()