Cascading after_update operations #7986
Replies: 1 comment 5 replies
-
OK so two general strategies:
For option one, you need to query the database to get a hold of not just id=2, but also id=1. the after_update event is run after the session has already figured out all the changes it will be making, so there's no automatic system that an UPDATE on row id=2 would cause the unit of work to actually trigger on that row. in other words, inside of after_update(), you need to emit the SQL for everything that needs to happen, not just part of it. if you're on PostgreSQL you could probably write a single UPDATE statement that uses WITH RECURSIVE to update all the rows at once, background on this syntax is at https://www.postgresql.org/docs/current/queries-with.html which SQLAlchemy supports. otherwise, the less fancy way is to keep SELECTing the parent row until parent_id=NULL and run an UPDATE on each one, something like this @event.listens_for(OperationNode, "after_update")
def after_update_trigger_parent_sync(mapper, connection, operation_node):
insp = db.inspect(operation_node)
state_history = insp.attrs["state"].load_history()
# Update aggregated fields of parent when a child has changes
if operation_node.parent_id \
and state_history.has_changes():
operation_node_table = OperationNode.__table__
parent_id = operation_node.parent_id
while parent_id is not None:
connection.execute(
operation_node_table.update().
where(operation_node_table.c.id == parent_id).
values(state="completed")
)
parent_id = connection.scalar(
select(operation_node_table.c.parent_id).
where(operation_node_table.c.id == parent_id)
) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
We have a parent/child table and want to be able to propagate updates up from the children/leaves to the parent root.
For example, given we have a structure like
When
child 3
state gets updated tocompleted
we want to update the state of the parent2
and its parent1
tocompleted
as well. We can do that when it's one level of separation, but for two levels the root node never gets updated. So node2
will get updated tocompleted
but1
is stuckin-progress
Here's what we have
so when we do
only the direct parent
2
gets updated from theafter_update
and not the root1
. Theafter_update
doesn't trigger the second time :(. Would be happy to share more code/context if needed.Are we missing something? Or is there a good example of this same use case out there? Any help is appreciated as we are very stuck!
Using sqlalchemy
1.3.24
andFlask-SQLAlchemy
2.4.4
This is copied from my stack overflow question here
Beta Was this translation helpful? Give feedback.
All reactions