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)
那么,我该如何提拔某人呢?
使用单独的表(在 SQLAlchemy 中映射到不同的类)来完全表示不同角色中的同一实体,这种做法介于非常可疑和彻底的反模式之间——正是因为您遇到的问题:实体的角色可以更改(在这里,通过升级),但是更改代表同一实体的 SQL 表/SQLAlchemy 类会完全遇到您刚刚遇到的问题。
我建议更改您的数据模型 - 例如,向所有员工添加一个字段,以确定他们是否是经理,然后Manager
完全丢失该表。如果您坚持要保留此数据模型,那么晋升将变得相当困难......:
复制内存中正在晋升的员工身份的所有数据
从数据库中删除所述实体
现在,创建管理器实体,将您保存的数据复制到其中 sub(1),并将其保存到数据库中
我无法想象为了保持现在的模式而使用这些复杂性是值得的......