2013-07-03 88 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