Skip to content

fix(#153): Ghost objects removed from the in-memory python list of the parent#160

Open
Anubhav-2003 wants to merge 3 commits intocorridor:mainfrom
Anubhav-2003:fix-issue-153
Open

fix(#153): Ghost objects removed from the in-memory python list of the parent#160
Anubhav-2003 wants to merge 3 commits intocorridor:mainfrom
Anubhav-2003:fix-issue-153

Conversation

@Anubhav-2003
Copy link
Copy Markdown

When we were reverting a relationship where a child object was marked for deletion, it was not being removed from the Python's in-memory data-structure (collection). This left 'ghost' objects in the collection. If an autoFlush occurred, SQLAlchemy attempted to lazy-load deferred columns for these ghost objects, causing a KeyError: Deferred loader failed crash, which was especially prevalent if we had a polymorphic sub-class. This fix ensures the items are actively removed from the collection list in memory using collection.remove(value), keeping the Python state perfectly synced with the database session state.

…t of the parent

When we were reverting a relationship where a child object was marked for deletion, it was not being removed from the Python's in-memory data-structure (collection). This left 'ghost' objects in the collection. If an autoflush occurred, SQLAlchemy attempted to lazy-load deferred columns for these ghost objects, causing a KeyError: Deferred loader failed crash, which was especially prevalent if we had a polymorphic sub-class. This fix ensures the items are actively removed from the collection list in memory using collection.remove(value), keeping the Python state perfectly synced with the database session state.

assert len(reverted_car.parts) == 0

with pytest.raises(IndexError):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert len(reverted_car.parts) == 0 should be enough?

you can try doing self.session.flush() and check that it should not raise KeyError (to reproduce original error mentioned in commit msg).

Copy link
Copy Markdown
Author

@Anubhav-2003 Anubhav-2003 Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert len(reverted_car.parts) == 0 should be enough?

you can try doing self.session.flush() and check that it should not raise KeyError (to reproduce original error mentioned in commit msg).

Thank You Ashish for nudging me in the right direction. So essentially the key error was still happening when I tried to flush, so just removing the deleted objects from the in-memory python list wasn't enough. So what I did now is essentially ensure that if something is not in memory and it is already marked for deletion then it is never lazy loaded, and the record just marks it with None. This actually matches the pattern of how we handle non-polymorphic objects, when we can't safely read a value from a deleted object.

Please let me know if I need to make any more changes,
Regards,
Anubhav

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants