0

I am writing a test for this function which simply grabs an object from a DB.

The test assertion is that this retrieved object is equal to the previously created object, which is what was written to the DB.

def test_get_dupe_check_and_rules(engine):
    test_lead = Lead(id='test_lead')
    test_dupe_rule = DupeRule(hours=24,
                              found_count=1,
                              dupe_limit='1',
                              result='failed')
    test_dupe_check = DupeCheck(lead=test_lead, result='failed')
    test_dupe_check.dupe_rules.append(test_dupe_rule)

    with Session(engine) as db_session:
        db_session.add(test_lead)
        db_session.add(test_dupe_check)
        db_session.commit()

    check = get_dupe_check_and_rules(test_lead, engine)

    assert check == test_dupe_check

This will ALWAYS fail when run -- except when in DEBUG mode, and the variables pane is kept open with an eye on the class attributes. If the variables pane is not left open, and once db_session.commit() is run, it seems everything regarding the local objects created up to that point is forgotten. The returned 'check' object is NOT the issue.

Instead of values in the attributes for those locally created objects, they are replaced by 'Parent instance <DupeCheck at 0x101c889c0> is not bound to a Session; lazy load operation of attribute 'lead' cannot proceed (Background on this error at: https://sqlalche.me/e/14/bhk3)'. But..this was a local object only inserted to the DB, not queried from it.

test_dupe_check has now become an EMPTY DupeCheck() class, thus failing the assertion. How/why does this happen?

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
doublea
  • 33
  • 4
  • Does this answer your question? [SQLAlchemy, get object not bound to a Session](https://stackoverflow.com/questions/8253978/sqlalchemy-get-object-not-bound-to-a-session) – snakecharmerb Mar 16 '23 at 20:26
  • Not quite -- the surprising thing here is that I can't access the objects created locally OUTSIDE of any session after it commits. The detached state is NOT coming from any objects that I've queried. I've fixed the issue by adding a db_session.refresh(object_name_here) after the commit for any objects I'll need later. – doublea Mar 16 '23 at 22:08
  • The code in the question doesn't seem to be runnable, so it's hard to know exactly what might be happening. But the debug behaviour is probably because the session's identity map is a `WeakInstanceDict`, and the debugger holds a reference to the objects in it so they aren't dereferenced when the session is closed. – snakecharmerb Mar 17 '23 at 15:12

1 Answers1

0

Not sure why - but I've fixed the issue by adding a db_session.refresh(object_name_here) after the commit for any objects I'll need later.

This detached state was surprising and unrelated to previous questions since the objects of interest here were ones I created locally, before and outside the scope of the session (and in no way related to a queried item); and they ended up losing their attributes anyway. I could swear that I've had very similar flows in the past and never had to use .refresh() after the .commit().

doublea
  • 33
  • 4