dav*_*ing 1 python sqlalchemy flask-sqlalchemy
我正在尝试检测何时创建或删除多对多关系,但我无法找出要侦听的正确事件。
假设我有一个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))
Run Code Online (Sandbox Code Playgroud)
我想要做的是检测某人何时加入或离开团队,并触发一个可以利用此信息执行某些操作的事件(例如在某处发送通知:“戴夫加入洋基队”;“莎拉离开大都会队”)。
我首先尝试将事件直接附加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
Run Code Online (Sandbox Code Playgroud)
但是,当我在团队中添加或删除用户时,此事件根本不会触发
我尝试简单地监听以下更新Team:
@event.listens_for(Team, 'after_update')
def test(mapper, connection, target):
# check current membership via `target.users`
Run Code Online (Sandbox Code Playgroud)
当成员资格发生变化时,这是正确触发的,但问题是我无法真正推理正在发生的事情。也许有人只是简单地编辑了团队名称,而成员身份根本没有改变。如果改变了,又是如何改变的?有人添加或删除了吗?
我有点不知道下一步该去哪里,或者如何获取必要的信息。
为了“检测某人何时加入或离开团队”,监听关系上的追加和删除事件:Team.users
@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)
Run Code Online (Sandbox Code Playgroud)
如果您将一个团队追加到用户的团队集合中,事件处理程序也会触发,这要归功于backref / back_populates两个关系属性之间的镜像操作。
| 归档时间: |
|
| 查看次数: |
2234 次 |
| 最近记录: |