本文目录导读:

SQLAlchemy 2.0 是一次重要的里程碑式更新,核心目标是统一和简化之前混乱的 ORM 与 Core 使用模式,并彻底拥抱 Python 异步(asyncio)。
核心变化可以总结为:“SQLAlchemy 1.x 的旧写法被标记为遗留,新项目应该使用 2.0 风格的写法”。
以下是 2.0 的关键更新内容:
核心哲学:统一 ORM 与 Core 的查询接口
这是 2.0 最根本的改变,在 1.x 中,ORM 查询使用 session.query(User),而 Core 使用 select(User.__table__),2.0 完全统一为 select() 构建器。
-
旧写法(1.x,已被移除或标记为遗留):
# ORM session.query(User).filter(User.name == 'Alice').all() # Core conn.execute(users_table.select().where(users_table.c.name == 'Alice')).fetchall()
-
新写法(2.0 风格,唯一推荐):
from sqlalchemy import select from sqlalchemy.orm import Session # ORM 和 Core 使用完全相同的 select() 对象 stmt = select(User).where(User.name == 'Alice') result = session.execute(stmt) users = result.scalars().all() # 注意需要 .scalars()
原生异步支持
SQLAlchemy 2.0 提供了官方的、一流的异步 IO 支持,无需再依赖 asyncpg 或 aiomysql 等第三方中间件。
-
新模块:
sqlalchemy.ext.asyncio -
核心类:
AsyncEngine,AsyncSession,AsyncConnection。 -
用法示例:
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/db") async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False) async def get_user(name): async with async_session() as session: stmt = select(User).where(User.name == name) result = await session.execute(stmt) return result.scalar_one_or_none()
弃用与移除
为了清理历史包袱,大量在 1.x 中标记为“遗留”的旧功能在 2.0 中被正式移除或弃用(通常会给出明确的迁移警告):
Session.query()被弃用:这是最影响老用户的变化。Query对象移除:不再有.filter(),.first(),.one()等 Query 方法,全部用select()+session.execute()替代。engine.execute()移除:必须显式使用connection.execute()。- 隐式
autocommit模式移除:现在必须显式调用session.commit()(即使默认 autocommit=False 但 1.x 中可能有隐式行为)。 result.fetchall()返回列表:过去返回ResultProxy或RowProxy等非标准类型,现在返回标准的list[Row]。
类型提示与声明性映射增强
-
Mapped 类型:新的
mapped_column()和Mapped类型注解,允许直接用 Python 原生类型定义表字段,不需要显式指定Column(Integer)。from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(50)) age: Mapped[int] -
自动从类型推断列类型:
age: Mapped[int]会自动映射为Integer,无需再写Column(Integer)。
新的统一型 Result 对象
session.execute() 返回一个统一的 CursorResult 对象,行为与 Core 的 Connection.execute() 完全一致。
- 返回行(Row):
result.all()返回list[Row],Row既支持按位置索引row[0],也支持按属性名访问row.name或row._mapping['name']。 - 获取 ORM 对象:必须显式调用
result.scalars()或result.scalar_one()来提取 ORM 实体。
更好的上下文管理器与生命周期管理
Session.open()/Session.in_transaction():新增方法允许查询 Session 状态。asyncio.run()兼容性:异步引擎和 Session 在asyncio.run()或 FastAPI 等框架中工作更稳定。
升级到 2.0 的最小建议
- 运行“未来模式”:在 1.4 版本中,可以通过设置
from __future__ import annotations和 SQLAlchemy 的future=True引擎参数,提前启用 2.0 的许多行为,有助于平滑过渡。 - 用
select()替代session.query():这是最大的改动。 - 启用
removals警告:在代码中开启import warnings; warnings.filterwarnings('error', '.*is legacy.*'),强制捕获所有弃用警告。 - 检查异步支持需求:如果项目使用 FastAPI 或 asyncio,2.0 的原生异步支持可以极大地简化代码(不再需要
aiosqlite+aiomysql等混搭)。
一句话总结:SQLAlchemy 2.0 让 ORM 和 Core 使用同一套 select() 语法,提供了原生的异步支持,并移除了大量旧版遗留的冗余写法。