On May 23, 2009, at 1:47 PM, Bob Farrell wrote:
> > Hi, using scoped_session(sessionmaker()) to create my sessions, if I > hammer a > request (using Pylons) by repeatedly clicking on a link that uses the > ORM > somewhat extensively for the relevant request, it seems that another > thread is > getting involved with SQLAlchemy internals and pulling the rug out > from under > its feet. that means you are sharing a mapped instance between threads. A mapped instance, when associated with a Session (i.e. not detatched), should be considered as an extension of that Session's internal state. The Session isn't threadsafe so you can't share a persistent instance between threads. If you are using some kind of persistent/ cached instances, make sure they are detatched from their original Session first, or merge() the instances in to the Session local to the request before using them (you can send the dont_load=True flag to merge() if you want to cut down on potentially needless SELECT statements). > And here's how I'm dealing with creating the sessions: > > threadlocal = threading.local() > > Session = scoped_session(sessionmaker(autocommit=True)) > Session.metadata = None > > def setup_db(): > if hasattr(threadlocal, 'engine'): > return > uri = config['main.engine.dburi'] > threadlocal.engine = create_engine(uri) > Session.configure(bind=threadlocal.engine) > if Session.metadata is None: > Session.metadata = MetaData(threadlocal.engine) > model.initialise(Session.metadata) the threading.local() is unnecessary...unless you are planning for the same application to be run with different .ini files in each thread which would be extremely unusual. scoped_session() already handles the thread local part for you as far as Sessions are concerned, and Engine objects are threadsafe. Session = scoped_session(sessionmaker(autocommit=True)) metadata = None def setup_db(): global metadata if metadata is not None: return uri = config['main.engine.dburi'] engine = create_engine(uri) Session.configure(bind=engine) metadata = MetaData(engine) model.initialise(metadata) if OTOH you had some reason for the threadlocal engines, then you dont want to use Session.configure, which configures the whole scoped_session(). You'd want to say Session(bind=my_threadlocal_engine). --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---