I'm trying to update an audit log table called 'loggings', here is the definition of the corresponding model:
class Logging(Base):
__tablename__ = 'loggings'
id = Column(GUID(), primary_key=True, nullable=False, default=uuid4)
target_id = Column(GUID(), doc="The ID of the altered object")
version = Column('version', Integer, default=0)
created_at = Column(DateTime, default=datetime.now)
modified_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
and two other models and an association table:
membership_table = Table('membership', Base.metadata,
Column('user_id', GUID(), ForeignKey('
user.id')),
Column('team_id', GUID(), ForeignKey('
team.id')),
PrimaryKeyConstraint('user_id', 'team_id'))
class User(ActivityMixin, Base): # Product
__tablename__ = "user"
id = Column(GUID(), primary_key=True, nullable=False, default=uuid4)
name = Column(String)
password = Column(String)
def __repr__(self): # optional
class Team(Base):
__tablename__ = 'team'
id = Column(GUID(), primary_key=True, nullable=False, default=uuid4)
name = Column(String(64))
users = relationship(lambda:User, secondary=membership_table, backref='teams')
I have an event listener/handler attached to the User class and another to the Team class:
@event.listens_for(User, 'after_update')
def create_logs_for_user(mapper, connection, target):
# logic to add a creation related record to the loggings table
@event.listens_for(User, 'after_update')
def update_logs_for_user(mapper, connection, target):
# logic to add user-updates records to the loggings table
@event.listens_for(Team, 'after_update')
def update_logs_for_team(mapper, connection, target):
# logic to add team-updates records to the loggings table
These are the operations that I perform:
[1]: from app import Logging, User, Team, session
[2]: user1 = User(name='qwerh')
[3]: session.add(user1)
[4]: session.commit() # after_insert gets fired here
[5]: team1 = Team(name="team1")
[6]: session.add(team1)
[7]: session.commit() # After this point, the users, team, and loggings tables have one record each, as expected.
[8]: user1.teams.append(team1)
[10]: session.commit() # Two update listeners are getting fired here! After the append.
Question:
When I perform the operation on step [8] above, the loggings table gets filled in twice, due to the "after_update" event getting fired by both the User and the Team models.
How do I prevent this from happening, I only want to capture the one event from the Team model, sorry I'm very new to SQLAlchemy, thank you!