SQLAlchemy 中的具体表继承模式详解

SQLAlchemy 中的具体表继承模式详解

sqlalchemy THIS IS NOT THE OFFICIAL REPO - PLEASE SUBMIT PRs ETC AT: http://github.com/sqlalchemy/sqlalchemy sqlalchemy 项目地址: https://gitcode.com/gh_mirrors/sql/sqlalchemy

什么是具体表继承

具体表继承(Concrete Table Inheritance)是 SQLAlchemy 提供的一种继承映射策略,也称为"每个类一个表"(table-per-class)模式。在这种模式下,继承体系中的每个类都对应数据库中的一个独立表,每个表都包含该类的所有属性(包括继承的属性)。

具体表继承的特点

  1. 独立表结构:每个子类都有自己完整的表结构,包含所有字段
  2. 无公共基表:与联合表继承不同,基类Person也有对应的表
  3. 多态查询:可以通过基类查询所有子类实例
  4. 明确标识:每个表通过polymorphic_identity标识具体类型

代码解析

基础设置

intpk = Annotated[int, mapped_column(primary_key=True)]
str50 = Annotated[str, mapped_column(String(50))]

这里定义了两个类型注解,用于简化列定义:

  • intpk:整数主键
  • str50:长度50的字符串

基类定义

class Person(ConcreteBase, Base):
    __tablename__ = "person"
    id: Mapped[intpk]
    company_id: Mapped[int] = mapped_column(ForeignKey("company.id"))
    name: Mapped[str50]
    
    company: Mapped[Company] = relationship(back_populates="employees")
    
    __mapper_args__ = {
        "polymorphic_identity": "person",
    }

关键点:

  • 继承自ConcreteBaseBaseConcreteBase是具体继承必需的
  • 定义了所有子类共有的字段:id、company_id和name
  • 设置了多态标识polymorphic_identity

子类定义

class Engineer(Person):
    __tablename__ = "engineer"
    
    id: Mapped[int] = mapped_column(primary_key=True)
    company_id: Mapped[int] = mapped_column(ForeignKey("company.id"))
    name: Mapped[str50]
    status: Mapped[str50]
    engineer_name: Mapped[str50]
    primary_language: Mapped[str50]
    
    __mapper_args__ = {"polymorphic_identity": "engineer", "concrete": True}

关键点:

  • 必须重新定义所有字段,包括继承的字段
  • __mapper_args__中必须设置concrete=True
  • 有自己的polymorphic_identity

多态查询

eng_manager = with_polymorphic(Person, "*")
session.scalars(
    select(eng_manager).filter(
        or_(
            eng_manager.Engineer.engineer_name == "engineer1",
            eng_manager.Manager.manager_name == "manager2",
        )
    )
).all()

with_polymorphic允许我们同时查询基类和子类的属性,"*"表示加载所有子类。

具体表继承的优缺点

优点

  1. 查询性能好,不需要多表连接
  2. 表结构清晰,每个类对应一个完整表
  3. 适合子类有大量特有属性的情况

缺点

  1. 需要重复定义继承的字段
  2. 修改基类字段需要同步修改所有子类
  3. 多态查询可能较复杂

适用场景

具体表继承适合以下情况:

  • 继承层次较浅
  • 子类有大量特有属性
  • 多态查询不是主要操作
  • 需要避免表连接带来的性能问题

总结

SQLAlchemy的具体表继承提供了一种高效的继承映射方式,特别适合子类差异较大的场景。通过本文的示例和解析,开发者可以更好地理解和使用这一特性,在自己的项目中实现合适的继承策略。

sqlalchemy THIS IS NOT THE OFFICIAL REPO - PLEASE SUBMIT PRs ETC AT: http://github.com/sqlalchemy/sqlalchemy sqlalchemy 项目地址: https://gitcode.com/gh_mirrors/sql/sqlalchemy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

井队湛Heath

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值