First, let me say that I'm using sqlalchemy version 0.5.8. We have a
large and complex application and changing to sa 0.6 is expensive, so
I would like, if possible, to find a solution for 0.5. I'm using
sqlalchemy since version 0.1.

Problem: objects are one moment inside a session an the other moment
are not.

Setup:

Session is in weak_identity_map=False mode:

   maker = sessionmaker(autoflush=True, autocommit=False,
        weak_identity_map=False,
        extension=[ZopeTransactionExtension(), EpiSessionExtension()])
    DBSession = scoped_session(maker)

All objects are immediately added to session:

    campaign = Campaign(...)
    DBSession.add(campaign)

Plus, the reference to object is kept locally.
Plus, the object is assigned to another relation property:

    qitem = QItem(campaign=campaign, ...)
    DBSession.add(qitem)

Now, the problem occurs at two different random points. Both time
the garbage collector is collecting the garbage before the problem
presents itself. This may have nothing to do with a problem.

Everything happens inside a single thread.

First case:

    campaign = Campaign(...)
    DBSession.add(campaign)
    ...
    # called indirectly because of lots of queries
    DBSession.flush()
    print campaign.id  # 206

    # A: the (<Campaign>, 206) is inside the keys
    print DBSession.identity_map.keys()

    contact = DBSession.query(...).one()
    # garbage is collected while this runs
    # I can see it because of gc.set_debug(...)
    # However, campaign is referenced locally and gc
    # leaves it, but maybe some other internal SA object
    # is collected.

    # B: the (<Campaign>, 206) is no longer present
    print DBSession.identity_map.keys()

Second case, very similar, but problem appears at a later point:

    campaign = Campaign(...)
    DBSession.add(campaign)
    DBSession.flush()
    print campaign.id  # 207
    contact = DBSession.query(...).one()

    # Also, assign campaign to relational property of `qitem`
    qitem = QItem(campaign=campaign, ...)
    DBSession.add(qitem)

    # The (<Campaign>, 207) is inside the keys
    print DBSession.identity_map.keys()

    DBSession.flush() # called via commit by web controller
    # DB raises exception CONTACT_ID cannot be NULL

The exception is raised because the `campaign` object
again got expunged from session for some reason, even
though the `qitem` itself holds a reference to it.

Sometimes everything finishes just fine.

I'm loosing sleep over this problem.

Regards,
Tvrtko

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to