如何更新SQLAlchemy中的更新相关对象?

时间:2015-07-03 18:17:49

标签: python sqlalchemy

我在Rule和RuleStats对象之间有一对一的关系。我正在尝试修改规则上的任何字段更新时RuleStats上的last_updated字段。如果它们不是两个单独的类,它将看起来像这样。

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 个答案:

答案 0 :(得分: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中很可能存在一种在内部执行此操作的方法,但我没有足够的洞察力来告诉从哪里开始戳。