如何在SQLAlchemy中修改其他字段时更新关系

时间:2013-06-06 19:40:22

标签: python sqlalchemy

我在SQLAlchemy中有一个简单的Client模型,主要使用声明式。此模型具有name字段,并且与MetaphoneCode模型具有多对多关系。代码如下:

class MetaphoneCode(Base):
    """Represents a metaphone code
    """
    __tablename__ = 'mcodes'
    id = Column(Integer, Sequence('mcodes_seq_id'), primary_key=True)
    code = Column(String(20), index=True, nullable=False)


client_mcode_assoc_table = Table(
    'client_mcodes',
    Base.metadata,
    Column('client_id', ForeignKey('clients.id')),
    Column('mcode_id', ForeignKey('mcodes.id')))


class Client(Base):
    __tablename__ = 'clients'
    id = Column(Integer, Sequence('client_id_seq'), primary_key=True)
    name = Column(Unicode(100), index=True)
    mcodes = relationship('MetaphoneCode', secondary=client_mcode_assoc_table)

现在,由于变音代码必须在name本身发生变化时发生变化,我想表达这种需求,以便在我client.name = "John Doe"时,我想计算与这些名称相关的变音符代码(名字和姓氏)并更新mcodes关系。

更新:我找到了引用below的简单解决方案;所以我的问题最好说明为“ ORM属性事件系统是更新属性以响应另一个属性的最佳实践机制吗?

2 个答案:

答案 0 :(得分:0)

也许使用getter和setter可以解决问题。

SqlAlchemy提供了一种将getter和setter添加到模型属性的方法。我自己从未使用过它们。请参阅http://docs.sqlalchemy.org/en/rel_0_8/orm/extensions/hybrid.html

但是我不知道在这些setter中运行业务逻辑代码是否很好。也许更有经验的人会告诉我们。

答案 1 :(得分:0)

我设法通过使用事件来实现:

@event.listens_for(Client.name, 'set')
def update_mcodes(target, value, oldvalue, initiator):
    target.recalculate_mcodes(value)

仍然,这是推荐的方法吗?我将阅读@Xaqq建议的混合方法,并确定它是否比这个event更好。