我在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属性事件系统是更新属性以响应另一个属性的最佳实践机制吗?”
答案 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
更好。