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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---