现有实例上的 SQLAlchemy 类继承

Dr *_*ngo 5 python inheritance sqlalchemy

我正在使用 SQLAlchemy 的连接表继承模式,但使用其文档中的确切模式,我无法弄清楚如何将子类应用到父类的现有实例。

在他们的例子中:

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'employee',
        'polymorphic_on':type
    }

class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    engineer_name = Column(String(30))

    __mapper_args__ = {
        'polymorphic_identity':'engineer',
    }

class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    manager_name = Column(String(30))

    __mapper_args__ = {
        'polymorphic_identity':'manager',
    }
Run Code Online (Sandbox Code Playgroud)

...想象一下我已经有一名员工,他既不是工程师也不是经理,但后来他们得到了晋升。做这样的事情...

employee = Employee.query.get(id)
m = Manager()
m.employee = employee
m = session.merge(employee)
Run Code Online (Sandbox Code Playgroud)

...导致这个错误...

FlushError: New instance <Manager at 0x7f6bf5a35490> with identity key (<class 'models.Employee'>, conflicts with persistent instance <Employee at 0x7f6bf590d210>
Run Code Online (Sandbox Code Playgroud)

那么,我该如何提拔某人呢?

Ale*_*lli 4

使用单独的表(在 SQLAlchemy 中映射到不同的类)来完全表示不同角色中的同一实体,这种做法介于非常可疑和彻底的反模式之间——正是因为您遇到的问题:实体的角色可以更改(在这里,通过升级),但是更改代表同一实体的 SQL 表/SQLAlchemy 类会完全遇到您刚刚遇到的问题。

我建议更改您的数据模型 - 例如,向所有员工添加一个字段,以确定他们是否是经理,然后Manager完全丢失该表。如果您坚持要保留此数据模型,那么晋升将变得相当困难......:

  1. 复制内存中正在晋升的员工身份的所有数据

  2. 从数据库中删除所述实体

  3. 现在,创建管理器实体,将您保存的数据复制到其中 sub(1),并将其保存到数据库中

我无法想象为了保持现在的模式而使用这些复杂性是值得的......