如何让SQLAlchemy多个子类对象共享同一个父类实例?
解决方案
首先明确:你当前用的SQLAlchemyJoined Table多态继承模式,本身不支持一个父类(Employee)实例对应多个子类(Manager+Engineer)实例。因为多态继承依赖polymorphic_on字段(这里是type)来区分子类,每个Employee记录的type只能是单一值(比如"manager"或"engineer"),没法同时对应两个子类。
要实现一个Employee对应Manager和Engineer的需求,你需要放弃多态继承,改用关联关系来设计模型,具体如下:
修改后的模型代码
from sqlalchemy import ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship class Base(DeclarativeBase): pass class Employee(Base): __tablename__ = "employee" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] # 建立与子类的双向关联,uselist=False表示一对一 engineer: Mapped["Engineer"] = relationship(back_populates="employee", uselist=False) manager: Mapped["Manager"] = relationship(back_populates="employee", uselist=False) def __repr__(self): return f"Employee({self.name!r} {self.id!r})" class Engineer(Base): __tablename__ = "engineer" id: Mapped[int] = mapped_column(ForeignKey("employee.id"), primary_key=True) engineer_name: Mapped[str] # 关联到Employee employee: Mapped[Employee] = relationship(back_populates="engineer") class Manager(Base): __tablename__ = "manager" id: Mapped[int] = mapped_column(ForeignKey("employee.id"), primary_key=True) manager_name: Mapped[str] # 关联到Employee employee: Mapped[Employee] = relationship(back_populates="manager")
使用方式
先创建Employee实例,再基于同一个Employee创建Manager和Engineer:
# 创建Employee并提交 emp = Employee(name='name1') session.add(emp) session.commit() # 关联同一个Employee创建Manager和Engineer manager = Manager(id=emp.id, manager_name="manager1", employee=emp) engineer = Engineer(id=emp.id, engineer_name="engineer1", employee=emp) session.add_all([manager, engineer]) session.commit()
补充说明
如果你坚持想用继承语法,也可以让Engineer和Manager都继承自Employee,但去掉多态相关配置(__mapper_args__和polymorphic_on),本质还是关联关系,只是子类继承了Employee的字段,但查询时需要手动关联,不如上面的方案直接。
内容的提问来源于stack exchange,提问作者wsl
相关产品推荐
相关产品推荐

