声明式映射样式¶
正如 Declarative Mapping 中介绍的那样,Declarative Mapping 是在现代 SQLAlchemy 中构造 Map 的典型方式。本节将概述可用于 Declarative mapper 配置的表单。
使用声明式基类¶
最常见的方法是通过子类化 DeclarativeBase 超类来生成“Declarative Base
”类:
from sqlalchemy.orm import DeclarativeBase
# declarative base class
class Base(DeclarativeBase):
pass
还可以在给定现有
Registry
中将其分配为名为
注册表
:
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import registry
reg = registry()
# declarative base class
class Base(DeclarativeBase):
registry = reg
在 2.0 版更改: DeclarativeBase
超类取代了 declarative_base()
函数和
registry.generate_base()
方法;超类方法与 PEP 484 工具集成,无需使用插件。有关迁移说明,请参阅 ORM Declarative Models。
使用声明式基类,新的 Map 类被声明为 base 的子类:
from datetime import datetime
from typing import List
from typing import Optional
from sqlalchemy import ForeignKey
from sqlalchemy import func
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "user"
id = mapped_column(Integer, primary_key=True)
name: Mapped[str]
fullname: Mapped[Optional[str]]
nickname: Mapped[Optional[str]] = mapped_column(String(64))
create_date: Mapped[datetime] = mapped_column(insert_default=func.now())
addresses: Mapped[List["Address"]] = relationship(back_populates="user")
class Address(Base):
__tablename__ = "address"
id = mapped_column(Integer, primary_key=True)
user_id = mapped_column(ForeignKey("user.id"))
email_address: Mapped[str]
user: Mapped["User"] = relationship(back_populates="addresses")
在上面,Base
类用作要映射的新类的基础,如上所示,新映射的类 User
和 Address
就是构造的。
对于构造的每个子类,类的主体遵循声明式映射方法,该方法在幕后定义 Table
和 Mapper
对象,这些对象构成了一个完整的映射。
另请参阅
使用声明式的表配置 - 描述如何指定要生成的映射表
的组件,包括有关使用 mapped_column()
的注释和选项
构造以及它如何与 Mapped
注解类型交互
具有声明式的映射器配置 - 描述所有其他
Declarative 中 ORM 映射器配置的各个方面,包括
relationship()
配置、SQL 表达式和
Mapper
参数
使用 Decorator 的声明式映射 (无声明式基)¶
作为使用“声明性基”类的替代方法是使用类似于“经典”映射的命令式技术显式地将声明性映射应用于类,或者更简洁地使用装饰器。registry.mapped()
函数是一个类装饰器,可以应用于任何没有层次结构的 Python 类。否则,Python 类通常以声明式样式配置。
下面的示例使用 registry.mapped()
设置与上一节中所示相同的映射
decorator 而不是使用 DeclarativeBase
超类:
from datetime import datetime
from typing import List
from typing import Optional
from sqlalchemy import ForeignKey
from sqlalchemy import func
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
from sqlalchemy.orm import relationship
mapper_registry = registry()
@mapper_registry.mapped
class User:
__tablename__ = "user"
id = mapped_column(Integer, primary_key=True)
name: Mapped[str]
fullname: Mapped[Optional[str]]
nickname: Mapped[Optional[str]] = mapped_column(String(64))
create_date: Mapped[datetime] = mapped_column(insert_default=func.now())
addresses: Mapped[List["Address"]] = relationship(back_populates="user")
@mapper_registry.mapped
class Address:
__tablename__ = "address"
id = mapped_column(Integer, primary_key=True)
user_id = mapped_column(ForeignKey("user.id"))
email_address: Mapped[str]
user: Mapped["User"] = relationship(back_populates="addresses")
当使用上述样式时,特定类的映射将仅
如果 Decorator 直接应用于该类,则 continue 。对于继承
mappings(在 Mapping Class Inheritance Hierarchies中有详细描述),装饰器应该应用于要映射的每个子类:
from sqlalchemy.orm import registry
mapper_registry = registry()
@mapper_registry.mapped
class Person:
__tablename__ = "person"
person_id = mapped_column(Integer, primary_key=True)
type = mapped_column(String, nullable=False)
__mapper_args__ = {
"polymorphic_on": type,
"polymorphic_identity": "person",
}
@mapper_registry.mapped
class Employee(Person):
__tablename__ = "employee"
person_id = mapped_column(ForeignKey("person.person_id"), primary_key=True)
__mapper_args__ = {
"polymorphic_identity": "employee",
}
声明式表和
命令式表
table 配置样式可以与 Declarative Base 一起使用
或 Declarative mapping 的装饰器样式。
当将 SQLAlchemy 声明式映射与其他类插桩系统(如 dataclasses 和 attrs)结合使用时,映射的装饰器形式非常有用,但请注意,SQLAlchemy 2.0 现在还具有与 Declarative Base 类的数据类集成功能。