the net-change to "user1.teams" is likely sending it through the 
"after_update" event but no net SQL is being emitted if no actual columns 
have changed on user1.

you would need to adjust the logic in your application to more specifically 
check for those conditions in which you want to act upon an event.  for 
example, if you want the event only to occur when specific attributes were 
affected, you could try using the history interface to see if those 
attributes have net changes: 
https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.attributes.History
  
or you can use a method like session.is_modified(): 
https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.Session.is_modified

On Friday, December 23, 2022 at 12:23:04 PM UTC-5 bboym...@gmail.com wrote:

> 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
> return f"User {self.name}"
>
> 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!
>  
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/d2a54ca3-24fa-4cb4-bf9c-9e4d54245fa9n%40googlegroups.com.

Reply via email to