news 2026/6/15 18:43:50

SQLAlchemy 2.0 类型注解指南:`Mapped` 与 `mapped_column`

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQLAlchemy 2.0 类型注解指南:`Mapped` 与 `mapped_column`

简介

在 SQLAlchemy 1.4 和 2.0 中,ORM(对象关系映射)引入了一种新的声明式映射系统,核心组件是Mapped类型注解和mapped_column构造函数。这种新风格旨在提供更好的 Python 类型提示(Type Hinting)支持,解决旧版Column写法在静态代码分析(如 Pyright, MyPy)和 IDE 自动补全方面的问题。

解决的问题

1. 静态类型检查报错

这是最常见的问题。在旧版写法中,模型属性被定义为Column对象,例如:

id=Column(Integer,primary_key=True)

对于静态分析工具(如 Pyright),id的类型是Column[Integer]。然而,当你实例化模型对象访问user.id时,其实际值是int类型。

当你尝试将user.id传递给一个期望int的函数时,Pyright 会报错:

Argument of type “Column[Integer]” cannot be assigned to parameter of type “int”

Mapped解决了这个问题。它明确告诉类型检查器,虽然我们在类定义中使用了描述符,但在实例中该属性表现为指定的 Python 类型。

2. IDE 智能感知

由于类型明确,现代 IDE(如 VS Code, PyCharm)能更准确地提供代码补全和错误提示。例如,定义为Mapped[str | None]的字段,IDE 会提示你该字段可能为 None。

用法对比

1. 基本字段

旧写法 (Legacy):

fromsqlalchemyimportColumn,Integer,StringclassUser(Base):__tablename__="user"id=Column(Integer,primary_key=True)name=Column(String(50),nullable=False)email=Column(String(100))

新写法 (Modern - SQLAlchemy 2.0+):

fromsqlalchemy.ormimportMapped,mapped_columnfromsqlalchemyimportStringfromtypingimportOptionalclassUser(Base):__tablename__="user"# Mapped[int] 告诉类型检查器:实例中的 id 是 int 类型# mapped_column(...) 定义了数据库列的属性id:Mapped[int]=mapped_column(primary_key=True)# nullable=False 是默认的,对应 Mapped[str]name:Mapped[str]=mapped_column(String(50))# Optional[str] 或 str | None 对应 nullable=Trueemail:Mapped[Optional[str]]=mapped_column(String(100))

2. 复杂类型 (UUID, DateTime)

旧写法:

importuuidfromsqlalchemy.dialects.postgresqlimportUUIDfromsqlalchemyimportColumn,DateTime,funcclassDocument(Base):id=Column(UUID(as_uuid=True),primary_key=True,default=uuid.uuid4)created_at=Column(DateTime(timezone=True),server_default=func.now())

新写法:

importuuidfromdatetimeimportdatetimefromsqlalchemy.ormimportMapped,mapped_columnfromsqlalchemy.dialects.postgresqlimportUUIDfromsqlalchemyimportDateTime,funcclassDocument(Base):# 明确指定 id 是 uuid.UUID 类型id:Mapped[uuid.UUID]=mapped_column(UUID(as_uuid=True),primary_key=True,default=uuid.uuid4)# 明确指定 created_at 是 datetime 类型created_at:Mapped[datetime]=mapped_column(DateTime(timezone=True),server_default=func.now())

3. 外键与关系

旧写法:

fromsqlalchemyimportForeignKeyfromsqlalchemy.ormimportrelationshipclassPost(Base):user_id=Column(Integer,ForeignKey("user.id"))user=relationship("User")

新写法:

fromsqlalchemyimportForeignKeyfromsqlalchemy.ormimportMapped,mapped_column,relationshipclassPost(Base):user_id:Mapped[int]=mapped_column(ForeignKey("user.id"))# 这里的 relationship 也支持 Mapped 类型user:Mapped["User"]=relationship()

关键点总结

  1. 导入: 使用from sqlalchemy.orm import Mapped, mapped_column
  2. 类型注解: 必须为每个列添加 Python 类型注解(如: Mapped[int])。
  3. Nullable:
    • Mapped[str]隐含nullable=False
    • Mapped[Optional[str]]Mapped[str | None]隐含nullable=True
  4. SQL 类型: 在mapped_column()中通过第一个参数指定 SQL 类型(如String(50)),如果类型可以从 Python 类型推断(如int->Integer),则可以省略。但对于String(需要长度)或UUID等特殊类型,通常还是需要指定。

通过采用这种新写法,你的代码将更加健壮,更易于维护,并且能通过严格的静态类型检查。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 16:05:50

markdown制作幻灯片:用Marp展示PyTorch-CUDA-v2.8研究成果

用 Marp 轻松制作 PyTorch-CUDA 技术汇报幻灯片 在 AI 研究节奏越来越快的今天,一个常见的尴尬场景是:你在组会上展示最新实验结果时,PPT 上的代码片段还是三天前跑通的那个版本,而真正的训练日志早已更新了好几轮。更糟的是&…

作者头像 李华
网站建设 2026/6/15 14:00:48

jiyutrainer下载统计显示PyTorch-CUDA-v2.8最受欢迎

PyTorch-CUDA-v2.8 为何成为最受欢迎的AI开发镜像? 在深度学习项目启动的前几个小时,你是否也曾经历过这样的场景:刚配好的环境跑不通代码,torch.cuda.is_available() 返回 False,查了日志才发现是 CUDA 版本和驱动不…

作者头像 李华
网站建设 2026/6/15 17:54:48

神州路由器的OSPF路由两种认证

一、基础配置 RA: Router>ena Router#conf Router_config#host RA RA_config#int l0 RA_config_l0#ip add 1.1.1.1 255.255.255.255

作者头像 李华
网站建设 2026/6/15 17:33:30

2026亲测8款免费降AI率工具!一键降低AI率,AIGC从99%→5%!

说实话,最近在写论文的我,最大的痛点不是查重,而是那行让人窒息的“AI率”。 只要一检测,屏幕上红彤彤的“85% AIGC内容”,整个人都要裂开。 以前想着用AI写论文能轻松点,结果现在变成“写论文靠AI&#…

作者头像 李华