SQLAlchemy2.0更新了什么

wen python案例 1

本文目录导读:

SQLAlchemy2.0更新了什么

  1. 核心哲学:统一 ORM 与 Core 的查询接口
  2. 原生异步支持
  3. 弃用与移除
  4. 类型提示与声明性映射增强
  5. 新的统一型 Result 对象
  6. 更好的上下文管理器与生命周期管理
  7. 升级到 2.0 的最小建议

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 支持,无需再依赖 asyncpgaiomysql 等第三方中间件。

  • 新模块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() 返回列表:过去返回 ResultProxyRowProxy 等非标准类型,现在返回标准的 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.namerow._mapping['name']
  • 获取 ORM 对象:必须显式调用 result.scalars()result.scalar_one() 来提取 ORM 实体。

更好的上下文管理器与生命周期管理

  • Session.open() / Session.in_transaction():新增方法允许查询 Session 状态。
  • asyncio.run() 兼容性:异步引擎和 Session 在 asyncio.run() 或 FastAPI 等框架中工作更稳定。

升级到 2.0 的最小建议

  1. 运行“未来模式”:在 1.4 版本中,可以通过设置 from __future__ import annotations 和 SQLAlchemy 的 future=True 引擎参数,提前启用 2.0 的许多行为,有助于平滑过渡。
  2. select() 替代 session.query():这是最大的改动。
  3. 启用 removals 警告:在代码中开启 import warnings; warnings.filterwarnings('error', '.*is legacy.*'),强制捕获所有弃用警告。
  4. 检查异步支持需求:如果项目使用 FastAPI 或 asyncio,2.0 的原生异步支持可以极大地简化代码(不再需要 aiosqlite + aiomysql 等混搭)。

一句话总结:SQLAlchemy 2.0 让 ORM 和 Core 使用同一套 select() 语法,提供了原生的异步支持,并移除了大量旧版遗留的冗余写法。

抱歉,评论功能暂时关闭!