2015-07-03 73 views
2

我在規則和RuleStats對象之間有一對一的關係。我試圖在規則的任何字段更新時修改RuleStats上的last_updated字段。如果他們不是兩個單獨的類,它會看起來像這樣。如何更新SQLAlchemy中的更新相關對象?

class Rule(Base): 
    __tablename__ = 'rules' 

    def __init__(self, **kwargs): 
     Base.__init__(self, **kwargs) 
     self.stats = RuleStats(rule=self) 

    id = Column(Integer, autoincrement=True, primary_key=True) 
    description = Column(String, nullable=False, default='') 
    # ... more fields 

    last_updated = Column(DateTime, default=datetime.now, onupdate=datetime.now, nullable=False) 

但我怎麼做,如果我有兩個不同的對象,

class Rule(Base): 
    __tablename__ = 'rules' 

    def __init__(self, **kwargs): 
     Base.__init__(self, **kwargs) 
     self.stats = RuleStats(rule=self) 

    id = Column(Integer, autoincrement=True, primary_key=True) 
    description = Column(String, nullable=False, default='') 
    # ... more fields 

    stats = relationship('RuleStats', uselist=False, backref='rule', cascade='all, delete-orphan') 

class RuleStats(Base): 
    __tablename__ = 'rule_stats' 

    def __init__(self, **kwargs): 
     Base.__init__(self, **kwargs) 

    rule_id = Column(Integer, ForeignKey('rules.id'), primary_key=True) 
    last_updated = Column(DateTime, default=datetime.now, nullable=False) 

回答

1

我認爲最簡單的方法是

  • 製作功能Rule.update()只有通過這個做更新在你的應用程序中具體功能例如:

    from sqlalchemy.orm.attributes import set_attribute 
    
    class Rule: 
    
        def update(self, **kwargs): 
         """Update instance attributes and bump last_modified date in stats""" 
         for key, value in kwargs.items(): 
           set_attribute(self, key value) 
         self.stats.last_updated = now() 
    

然後:

rule.update(description="Python rocks!") 

如果你想使它對用戶透明,使RuleState不斷更新,即使你直接捅Rule屬性,你可以使用Python properties爲此。然而,這種方法導致更復雜的代碼庫,我不能直接推薦它。

或者,您可以使用數據庫觸發器在數據庫端執行更新。 Update trigger example for PostgreSQL

目前最有可能的存在的方法,先進的SQLAlchemy內部這樣做,但我沒有足夠的洞察力告訴從哪裏開始戳。

+0

感謝您的回覆。我想添加一個setter函數,但是我真的很想用SQLAlchemy自動完成此操作。這似乎不太可能在這個時候不掛鉤到'''before_flush''',所以我可能不得不回到這個解決方案。 –