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
-~----------~----~----~----~------~----~------~--~---

Reply via email to