我正在尝试检测创建或删除多对多关系的时间,但我无法找出正确的事件来监听。
假设我有User
模型和Team
模型,我正在使用成员资格表来定义哪些用户属于哪些团队。这是一个简单的模式(使用Flask-SQLAlchemy的基本模型):
membership_table = db.Table('membership', db.metadata,
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
db.Column('team_id', db.Integer, db.ForeignKey('team.id')),
db.PrimaryKeyConstraint('user_id', 'team_id'))
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))
teams = db.relationship('Team', secondary=membership_table, backref='users')
class Team(db.Model):
__tablename__ = 'team'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))
我想要做的是检测有人加入或离开团队,并触发可以对此信息做某事的事件(例如在某处发送通知:“Dave加入洋基队”;“Sarah离开大都会队”)
我首先尝试将after_insert
和after_delete
事件直接附加到成员资格表中,但这只是因为AttributeError: after_delete
异常而失败,这或多或少是我预期的,因为它不是像其他人一样的模特。
我尝试将set
听众附加到User.teams
:
@event.listens_for(User.teams, 'set')
def membership_updated(target, value, oldvalue, initiator):
# compare `oldvalue` to `newvalue` to determine membership change
但是,当我从团队中添加或删除用户时,此事件永远不会被触发
我尝试过只听取Team
的更新:
@event.listens_for(Team, 'after_update')
def test(mapper, connection, target):
# check current membership via `target.users`
当成员资格发生变化时,这是正确触发的,但问题是我无法真正解释发生了什么。也许有人只是编辑了团队名称,而且会员资格根本没有变化。如果它改变了,怎么样?有人添加或删除了吗?
我有点卡在下一步去哪里,或者如何获得必要的信息。
答案 0 :(得分:3)
为了检测有人加入或离开团队的时间"在Team.users
关系中收听append和remove个事件:
@event.listens_for(Team.users, 'append')
def receive_team_users_append(target, value, initiator):
print(value.name, 'added to team', target.name)
@event.listens_for(Team.users, 'remove')
def receive_team_users_append(target, value, initiator):
print(value.name, 'removed from team', target.name)
如果您将团队附加到用户的团队集合,事件处理程序也会触发,这要归功于两个关系属性之间的how backref / back_populates mirror operations。