2013-07-03 64 views
0

我正在使用SQLAlchemy开发一个Python项目。我有以下类(我忽略了这个问题的一些方法无关):SQLAlchemy:基于其他属性初始化属性

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从使用event_names列表cmd_id属性创建类的实例(也省略了,这是一个包含命令名称的简单列表)。

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

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

我已阅读文档,并找到有关ORM Event侦听器的一些信息,但它们对于这种简单情况似乎太多了。我还发现了关于属性事件的一些内容,但它们仅适用于column_propertyrelationship。有没有什么简短,优雅的方式来实现我想要的?

回答

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下的 “构造函数和对象的初始化”。

+0

我知道那里比映射器事件监听器更简单:) – Wookie88