9

I have a small thrift server in python that I use do some fast lookups. The server queries mysql via SqlAlchemy on the first request and shoves all returned objects into a dictionary so on subsequent requests no DB call is needed. I just get the object from the dict and then call some of the object methods needed to give the proper response.

Initially, everything is fine. However, after the server runs a while, I am getting this exception when accessing the sqlalchemy object methods:

Parent instance is not bound to a Session; lazy load operation of attribute 'rate' cannot proceed.

Strange, because I set eagerload('rate').

I cannot really see a pattern to this behavior, it only affects some objects. However, once it does affect an object it will continue to do so on each request until I restart my python server.

Any ideas?

Tony
  • 2,037
  • 3
  • 22
  • 22
  • I just noticed in one of the calls to the eagerloaded 'rate' property, I am using a different lookup path than the way it was eagerloaded, so I have modified that and will see if it makes a difference. – Tony Nov 23 '10 at 06:23
  • 1
    How is rate defined? Is it a sa.orm.relation? Maybe post some example code. – Gary van der Merwe May 19 '11 at 09:57

1 Answers1

10

You probably cache objects between the requests, and when the commit happens, session object is getting cleared, invalidating your objects. If you start your server via some multithreaded web server that starts workers as needed, that explains why there's no pattern. If you dont want to get the bottom of this and just need a quick fix, this will always work:

if obj not in session:
    obj = session.query(ObjClass).get(obj.id)

The proper solution would be to make sure you don't cache objects between requests.

thule
  • 4,034
  • 21
  • 31
  • Yup. In my case, it was the fact that a celery task was called synchronously and the fact that it passes object as a parameter instead of a primitive type. Celery was running in a different app environment and the session confused the SQLAlchemy with session scope. To fix it, simply `.delay()` the call and passing params by primitive value. – Devy Jan 08 '16 at 20:32