SQLAlchemy多态更新

时间:2015-06-11 13:05:05

标签: python database sqlalchemy

我有一个类Parent和它的两个子类Child和ChildOne 我能够为每个表添加数据并读取数据 现在我想更新Child类的行,使它成为ChildOne表中的一行,当我从“young”将类型更新为“old”时,我希望该行从child_one表中删除并添加到子表中,但是没有丢失“id”值(这是主键) SQLAlchemy本身有没有办法处理这个问题?或任何其他想法来实现这一目标?

from sqlalchemy import create_engine, ForeignKey
from sqlalchemy import Column, Integer, String, case, Boolean
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base, declared_attr

engine = create_engine('sqlite:///testing.db', echo=True)
Base = declarative_base()


class Parent(Base):
    __tablename__ = "parent"

    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)
    type = Column(String)

    def __init__(self, name):
        self.name = name
        self.type = type

    __mapper_args__ = {
        'polymorphic_identity':'parent',
        'polymorphic_on': case(
            [(type == "young", "child_one"), 
            (type == "old", "child")]
            )
    }


class Child(Parent):
    __tablename__ = "child"

    id = Column(Integer, ForeignKey('parent.id'), primary_key=True)
    school = Column(String, default="some high school")

    def __init__(self, name, school):
        self.name = name
        self.type = type
        self.school = school

    __mapper_args__ = {
        'polymorphic_identity':'child'
    }


class ChildOne(Parent):
    __tablename__ = "child_one"

    id = Column(Integer, ForeignKey('parent.id'), primary_key=True)
    school = Column(String, default="UCLA")
    mode = Column(Boolean, default=1)
    bool = Column(Boolean, default=0)

    def __init__(self, name, type, school, mode, bool):
        self.name = name
        self.type = type
        self.school = school
        self.mode = mode
        self.bool = bool

    __mapper_args__ = {
        'polymorphic_identity':'child_one'
    }

1 个答案:

答案 0 :(得分:0)

from sqlalchemy import event

# standard decorator style
@event.listens_for(Child, 'after_update')
def receive_after_update(mapper, connection, target):
    "listen for the 'after_update' event"
    if target.type == "young":
        ChildOne(id=target.id)

But honestly, you should just be creating triggers in the database from something like this. It doesn't require overly complex sqlalchemy code.