2

Original problem I'm using sqlalchemy in our project. I registered few event listeners for my model like so.

@event.listens_for(Post, 'after_update')
@event.listens_for(Post, 'after_insert')

Somewhere else in the code I update the view_counter property of my model.

post.view_counter += 1
DBSession.flush()

Now, since view_counter is not something I regard as content update, I want to supress firing of after_update event in sqlalchemy for this specific update. Is there a way to do it via ORM or is the only way to just do raw SQL update bypassing ORM entirely?

EDIT After some poking around I realized there is another problem, the property is set by Postgresql itself

date_last_updated = Column(SA_DateTime, default=DateTime.now, onupdate=DateTime.now, nullable=False, index=True)

Problem
So the question is, how to update a sqlalchemy model without triggering Postgresql update.

1 Answer 1

2

If you're able to make changes to the decorated function, it should be possible to use the passed arguments to determine which fields were modified, albeit through a little bit of a workaround. I'm afraid I haven't been able to test this yet, but I hope it helps!

@event.listens_for(Post, 'after_update', raw=True)
@event.listens_for(Post, 'after_insert', raw=True)
def myfunc(mapper, connection, target):
    # Values have been modified
    if target.session.is_modified(target, include_collections=False):
        # view_counter is the only modified value, the hook can be aborted
        if set(target.dict.keys()) - target.unmodified == {'view_counter'}:
            return
    <...the rest of the function...>
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, this did solve original problem, but I discovered another one, I've updated the question.
You could replace onupdate=DateTime.now with onupdate=myupdatefunc and define your own context-aware update function using docs.sqlalchemy.org/en/13/core/…
Another option would be to explicitly set the updated_at value to the same value it already has, triggering an "update" of the field should mean that the onupdate clause is not executed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.