views:

567

answers:

2

I'm writing a little web app with webpy, and I'm wondering if anyone has any information on a little problem I'm having.

I've written a little ORM system, and it seems to be working pretty well. Ideally I'd like to stitch it in with webpy, but it appears that just using it as is causes thread issues (DB connection is instantiated/accessed across thread boundaries, or so the exception states).

Does anyone know how I can (within the webpy) create my DB connection on the same thread as the rest of the page handling code will be?

A: 

I'll give this one a try. Disclaimer: I have no experience with the web.py framework.

I suggest you try the following:

(1) Create a global threading.local instance to keep track of your thread local objects (in your case, it will keep track of only one object, a database session).

import threading
serving = threading.local()

(2) At the start of each request, create a db connection/session and save it in the threading.local instance. If I understand the web.py documentation correctly, you can do the following:

def setup_dbconnection(handler): 
    serving.dbconnection = create_dbconnection(...)
    try:
        return handler()
    finally:
        serving.dbconnection.close() # or similar

app.add_processor(setup_dbconnection)

(3) In your controller methods (if they're called that in web.py?), whenever you need a db connection, use serving.dbconnection.

codeape
+2  A: 

We use SQLAlchemy with web.py and use hooks to create and close db connections per request. SQLAlchemy handles pooling, so not every connection is a tcp connection.

The thread local storage you want to use is web.ctx ie. any time you access web.ctx you only see properties set by that thread.

Our code looks something like this:

def sa_load_hook():
    web.ctx.sadb = Session()

def sa_unload_hook():
    web.ctx.sadb.close()

web.loadhooks['sasession'] = sa_load_hook
web.unloadhooks['sasession'] = sa_unload_hook

Replace Session with your db connection function and it should work fine for you.