Open mangecoeur opened 4 months ago
Coming back to this, since we've been having some issues making sure both sqlalchemy updates and solara updates happen. Here are just some general thoughts for future reference.
The problem is that sqlalchemy thrives of mutation, with fancy change handling so it can push minimal updates to the database. But solara does change tracking through object equality checking which means often you need a new copy of an object to force an update. It also merges using the merge_state function that makes copies.
I'm wondering if it would work to set a custom merge_state
function where we would supply the sqlalchemy session and use it's own merge
function. Currently this isn't easily possible because merge_state is set as a default value for the merge callback in ValueBase, but is not passed as a keyword argument from the inheriting classes (KernelStore) or the enclosing class (Reactive._storage).
There is also use_sync_external_store
which looks like it could do the trick using sqlalchemy events.
SqlAlchemy provides powerful object models for objects mapped to database, and with version 2.0 supports models mapped as dataclasses.
Using sqlalchemy dataclass models within reactive shows some odd behaviours.
Keeping only one side of the back_populates reference and constructing children using parent_id instead of parent object works as a workaround. The suspicion is that the reactive update calls dataclass.replace(), which causes the child object to be re-constructed with the parent as an argument which triggers sqlalchemy to add the child object again as if it was a new object.