here is an interesting thread related to this subject:

http://www.modpython.org/pipermail/mod_python/2006-August/021854.html

this person reported problems with threading.local() in conjunction  
with mod_python.   Its unfortunate that I can't locate any Python bug  
reports or anything to confirm it.  But it suggests that if this is  
the problem, then this patch on your end would resolve the issue:

Index: lib/sqlalchemy/pool.py
===================================================================
--- lib/sqlalchemy/pool.py      (revision 5293)
+++ lib/sqlalchemy/pool.py      (working copy)
@@ -484,7 +484,8 @@
      def __init__(self, creator, pool_size=5, **params):
          params['use_threadlocal'] = True
          Pool.__init__(self, creator, **params)
-        self._conn = threading.local()
+        from _threading_local import local
+        self._conn = local()
          self._all_conns = set()
          self.size = pool_size

If threading.local() is actually broken in native embedded  
environments, that's pretty disturbing.



On Nov 15, 2008, at 10:33 PM, Randy Syring wrote:

>
>
> On Nov 15, 6:39 pm, Michael Bayer <[EMAIL PROTECTED]> wrote:
>
> Thank you so much for your response, I am extremely grateful.
> However, I am still getting exceptions thrown from SQLite for sharing
> connections across threads.
>
>> The explicit connection as well as the "threadlocal" strategy are all
>> unnecessary here.   Configuring the sessionmaker() with a bind to a
>> plain engine i.e. create_engine('sqlite:///mydb.sql'), and making  
>> sure
>> sess.close() is called within the WSGI method are all that's needed.
>>
>> Pattern here is:
>>
>> Session = sessionmaker(bind=engine)
>> sess = Session()
>> try:
>>        < work with session>
>> finally:
>>        sess.close()
>>
>> Alternatively, as I noted previously 
>> inhttp://www.sqlalchemy.org/docs/05/session.html#unitofwork_contextual_ 
>> ...
>> , using scoped_session in conjunction with Session.remove() at the  
>> end
>> of the request works here as well, as I mentioned this is the  
>> practice
>> that is standard among popular web frameworks such as Pylons.
>>
>> Pattern here is :
>>
>> Session = scoped_session(sessionmaker(bind=engine))
>> sess = Session()
>> try:
>>        < work with session>
>> finally:
>>        Session.remove()
>
>
> I have updated my code per your directions, I believe:
>
> http://paste.pocoo.org/show/91318/
>
> I wasn't 100% sure where Session should be instantiated.  At the
> module level or at the request level.  Look at the docs and also at
> how Pylons does it, it seems that it should be instantiated at the
> module/application level.  My example above shows it that way, but I
> tried it the other way as well, with similar results.
>
> I also tried using a non-contextual session and ended up with the same
> results.
>
> Note in the code above that I have added some exception logging to
> tell where the exceptions are being generated.
>
>
>> The
>> Session is then garbage collected via asynchronous gc, the connection
>> is returned to the pool, and the pool's attempt to rollback() the
>> connection before returning to the pool raises the exception.  The
>> exception does not propagate outwards since it is during garbage
>> collection.  This is why the program keeps running without overall
>> issue (except for your ISAPI plugin which probably cannot handle that
>> kind of thing gracefully).
>
> Well, I am not sure about the details, but the log messages say that
> the exceptions are being thrown by my query() call, not during garbage
> collection.  Out of 100 requests, 14 ended in failures, and all of
> them were from my query() call.  The log files also give some more
> information which I hope will be helpful:
>
> 2008-11-15 21:53:51,015 INFO (5548) Connection <sqlite3.Connection
> object at 0x01F41AA0> checked out from pool
> 2008-11-15 21:53:51,015 INFO (5548) Connection <sqlite3.Connection
> object at 0x01F41AA0> being returned to pool
>
> <snip>
>
> 2008-11-15 21:53:51,515 INFO (5412) start response
> 2008-11-15 21:53:51,515 INFO (5412) Connection <sqlite3.Connection
> object at 0x01F41AA0> checked out from pool
>
> Ok, note above that thread 5548 checks out a connection object.  Then
> a little while later, thread 5412 also checks out the *same*
> connection object (technically, the connection object at that memory
> location could have been closed and replaced by a new one, but the
> logs don't show the connection being closed and the errors below would
> seem to confirm its the same object).  My understanding of what you
> have said about the SingletonThreadPool is that that should not
> happen.  Once 5412 checks out the connection object created in 5548,
> the following log output is generated:
>
> 2008-11-15 21:53:51,515 INFO (5412) Invalidate connection
> <sqlite3.Connection object at 0x01F41AA0> (reason:
> ProgrammingError:SQLite objects created in a thread can only be used
> in that same thread.The object was created in thread id 5548 and this
> is thread id 5412)
> 2008-11-15 21:53:51,515 INFO (5412) Closing connection
> <sqlite3.Connection object at 0x01F41AA0>
> 2008-11-15 21:53:51,515 INFO (5412) Connection <sqlite3.Connection
> object at 0x01F41AA0> threw an error on close: SQLite objects created
> in a thread can only be used in that same thread.The object was
> created in thread id 5548 and this is thread id 5412
> 2008-11-15 21:53:51,515 INFO (5412) Connection None being returned to
> pool
> 2008-11-15 21:53:51,515 INFO (5412) query exception:
> (ProgrammingError) SQLite objects created in a thread can only be used
> in that same thread.The object was created in thread id 5548 and this
> is thread id 5412 None [{}]
> 2008-11-15 21:53:51,515 INFO (5412) end response
>
> Are you sure this isn't a problem with pulling the wrong connection
> from the pool?
>
>> Still another way to do this is to eliminate the source of the error
>> at the pool level - ultimately, the SingletonThreadPool is attempting
>> to return the connection to the pool and call rollback() on it, which
>> is why the threaded access fails.  If you use NullPool, the  
>> connection
>> is thrown away entirely when closed and nothing is done to it.   Any
>> version of your program will run without errors if NullPool is used -
>> you'll just get a little overhead in opening more connections which  
>> in
>> the case of file-based sqlite is extremely miniscule.  In that case
>> you can even reuse the same Session object repeatedly across requests
>> as long as scoped_session is in place to enforce one-thread-per- 
>> session.
>
> I was able to use a NullPool successfully to alleviate my problems.
> However, it still doesn't seem right that I can't get singleton thread
> pooling to work.  Am I still doing something wrong?
> >


--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to