SQLAlchemy:基于其他属性初始化属性

时间:2013-07-03 17:11:34

标签: python orm sqlalchemy

我正在使用SQLAlchemy开发一个Python项目。我有以下课程(我省略了一些与问题无关的方法):

class Cmd(Base):
    __tablename__ = "commands"
    dbid = Column(Integer, Sequence("commands_seq"), primary_key = True)
    cmd_id = Column(SmallInteger)
    instance_dbid =  Column(Integer, ForeignKey("instances.dbid"))
    type = Column(String(20))

    __mapper_args__ = {
    "polymorphic_on" : type,
    "polymorphic_identity" : "Cmd"
    }

    def __init__(self, cmd_id):
        self.cmd_id = cmd_id
        self.cmd_name = event_names[self.cmd_id]

如您所见,在初始化类的实例时,属性cmd_name是使用cmd_id列表从event_names属性创建的(也省略了,它是一个包含命令名称的简单列表)。 / p>

我创建对象Cmd,添加会话,提交会话。关闭应用程序并再次启动它后,我尝试使用SQLAlchemy查询加载此Cmd。该对象已加载,但当然未调用__init__且未设置cmd_name

我想知道在获取带有查询的self.cmd_name = event_names[self.cmd_id]对象后是否有一些简单的方法来执行某些代码(Cmd)。当然,我可以做一个特殊的方法,并在查询后始终启动它,但我正在寻求更优雅,自动的方式。

我已阅读文档并找到有关ORM事件监听器的一些信息,但对于这种简单的情况,它们似乎太多了。我还找到了有关属性事件的内容,但它们仅适用于column_propertyrelationship。是否有任何简短,优雅的方式来达到我的目的?

1 个答案:

答案 0 :(得分:1)

您可以使用@reconstructor装饰器:

from sqlalchemy.orm import reconstructor
class Cmd(Base):
    __tablename__ = "commands"
    dbid = Column(Integer, Sequence("commands_seq"), primary_key = True)
    cmd_id = Column(SmallInteger)
    instance_dbid =  Column(Integer, ForeignKey("instances.dbid"))
    type = Column(String(20))

    __mapper_args__ = {
    "polymorphic_on" : type,
    "polymorphic_identity" : "Cmd"
    }

    def __init__(self, cmd_id):
        self.cmd_id = cmd_id
        self.cmd_name = event_names[self.cmd_id]

    @reconstructor
    def init_db_load(self):
        self.cmd_name = event_names[self.cmd_id]

请参阅“构造函数和对象初始化”下的doc