SQLAlchemy 2.0 類型注解指南之Mapped與mapped_column詳解
簡(jiǎn)介
在 SQLAlchemy 1.4 和 2.0 中,ORM(對(duì)象關(guān)系映射)引入了一種新的聲明式映射系統(tǒng),核心組件是 Mapped 類型注解和 mapped_column 構(gòu)造函數(shù)。這種新風(fēng)格旨在提供更好的 Python 類型提示(Type Hinting)支持,解決舊版 Column 寫法在靜態(tài)代碼分析(如 Pyright, MyPy)和 IDE 自動(dòng)補(bǔ)全方面的問(wèn)題。
解決的問(wèn)題
1. 靜態(tài)類型檢查報(bào)錯(cuò)
這是最常見的問(wèn)題。在舊版寫法中,模型屬性被定義為 Column 對(duì)象,例如:
id = Column(Integer, primary_key=True)
對(duì)于靜態(tài)分析工具(如 Pyright),id 的類型是 Column[Integer]。然而,當(dāng)你實(shí)例化模型對(duì)象訪問(wèn) user.id 時(shí),其實(shí)際值是 int 類型。
當(dāng)你嘗試將 user.id 傳遞給一個(gè)期望 int 的函數(shù)時(shí),Pyright 會(huì)報(bào)錯(cuò):
Argument of type “Column[Integer]” cannot be assigned to parameter of type “int”
Mapped 解決了這個(gè)問(wèn)題。它明確告訴類型檢查器,雖然我們?cè)陬惗x中使用了描述符,但在實(shí)例中該屬性表現(xiàn)為指定的 Python 類型。
2. IDE 智能感知
由于類型明確,現(xiàn)代 IDE(如 VS Code, PyCharm)能更準(zhǔn)確地提供代碼補(bǔ)全和錯(cuò)誤提示。例如,定義為 Mapped[str | None] 的字段,IDE 會(huì)提示你該字段可能為 None。
用法對(duì)比
1. 基本字段
舊寫法 (Legacy):
from sqlalchemy import Column, Integer, String
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False)
email = Column(String(100))新寫法 (Modern - SQLAlchemy 2.0+):
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import String
from typing import Optional
class User(Base):
__tablename__ = "user"
# Mapped[int] 告訴類型檢查器:實(shí)例中的 id 是 int 類型
# mapped_column(...) 定義了數(shù)據(jù)庫(kù)列的屬性
id: Mapped[int] = mapped_column(primary_key=True)
# nullable=False 是默認(rèn)的,對(duì)應(yīng) Mapped[str]
name: Mapped[str] = mapped_column(String(50))
# Optional[str] 或 str | None 對(duì)應(yīng) nullable=True
email: Mapped[Optional[str]] = mapped_column(String(100))2. 復(fù)雜類型 (UUID, DateTime)
舊寫法:
import uuid
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import Column, DateTime, func
class Document(Base):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
created_at = Column(DateTime(timezone=True), server_default=func.now())新寫法:
import uuid
from datetime import datetime
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import DateTime, func
class Document(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. 外鍵與關(guān)系
舊寫法:
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
class Post(Base):
user_id = Column(Integer, ForeignKey("user.id"))
user = relationship("User")新寫法:
from sqlalchemy import ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship
class Post(Base):
user_id: Mapped[int] = mapped_column(ForeignKey("user.id"))
# 這里的 relationship 也支持 Mapped 類型
user: Mapped["User"] = relationship()關(guān)鍵點(diǎn)總結(jié)
- 導(dǎo)入: 使用
from sqlalchemy.orm import Mapped, mapped_column。 - 類型注解: 必須為每個(gè)列添加 Python 類型注解(如
: Mapped[int])。 - Nullable:
Mapped[str]隱含nullable=False。Mapped[Optional[str]]或Mapped[str | None]隱含nullable=True。
- SQL 類型: 在
mapped_column()中通過(guò)第一個(gè)參數(shù)指定 SQL 類型(如String(50)),如果類型可以從 Python 類型推斷(如int->Integer),則可以省略。但對(duì)于String(需要長(zhǎng)度)或UUID等特殊類型,通常還是需要指定。
通過(guò)采用這種新寫法,你的代碼將更加健壯,更易于維護(hù),并且能通過(guò)嚴(yán)格的靜態(tài)類型檢查。
到此這篇關(guān)于SQLAlchemy 2.0 類型注解指南:`Mapped` 與 `mapped_column`的文章就介紹到這了,更多相關(guān)SQLAlchemy 2.0 類型注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python Django 通用視圖和錯(cuò)誤視圖的使用代碼
這篇文章主要介紹了Python Django 通用視圖和錯(cuò)誤視圖的使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
python的scikit-learn將特征轉(zhuǎn)成one-hot特征的方法
今天小編就為大家分享一篇python的scikit-learn將特征轉(zhuǎn)成one-hot特征的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
python進(jìn)程間數(shù)據(jù)交互的幾種實(shí)現(xiàn)方式
本文主要介紹了python進(jìn)程數(shù)據(jù)交互的幾種實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
Python個(gè)人博客程序開發(fā)實(shí)例框架設(shè)計(jì)
這篇文章主要介紹了怎樣用Java來(lái)實(shí)現(xiàn)一個(gè)完整的個(gè)人博客系統(tǒng),我們通過(guò)實(shí)操上手的方式可以高效的鞏固所學(xué)的基礎(chǔ)知識(shí),感興趣的朋友一起來(lái)看看吧2022-12-12
使用python+whoosh實(shí)現(xiàn)全文檢索
今天小編就為大家分享一篇使用python+whoosh實(shí)現(xiàn)全文檢索,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
Python時(shí)間和日期庫(kù)的實(shí)現(xiàn)
這篇文章主要介紹了Python時(shí)間和日期庫(kù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03

