Christian
Christian

Reputation: 577

SQLAlchemy: How to bind scoped session to request

I am new to sqlalchemy and it seems that I still miss several fundamental concepts. I want to use sqlalchemy to handle db interaction in a multi-thread web application.

So I start with

import sqlalchemy
from sqlalchemy                 import create_engine
from sqlalchemy.orm             import sessionmaker, scoped_session

engine          = create_engine('mysql://mydb')
session_factory = sessionmaker( autocommit  = False,
                                autoflush   = False,
                                bind        = engine )
Session         = scoped_session(session_factory)

I use a MoinMoin wiki that handles the requests, so I have an object macro.request containing the request.

I now have a method in some class, say

def do_sth():
    session = Session()
    # use the session to get some data from the db

Where and how do I tell the Session object which request it is linked to?

Reading Multi-threaded use of SQLAlchemy, it says

The ScopedSession object by default uses [threading.local()] as storage, so that a single Session is maintained for all who call upon the ScopedSession registry, but only within the scope of a single thread. Callers who call upon the registry in a different thread get a Session instance that is local to that other thread.

so " Callers who call upon the registry in a different thread get a Session instance that is local to that other thread."

How is a Session instance local if I never told it which request it is linked to?

Upvotes: 3

Views: 2773

Answers (1)

Christian
Christian

Reputation: 577

The SQLAlchemy documentation says

So our above example of scoped_session usage, where the same Session object is maintained across multiple calls, suggests that some process needs to be in place such that mutltiple calls across many threads don’t actually get a handle to the same session. We call this notion thread local storage, which means, a special object is used that will maintain a distinct object per each application thread. Python provides this via the threading.local() construct.

So even though I have not figured out how to obtain the current thread's pid from the given session, the threading module is used to link the session to the thread. In particular, one can check the session's hash key

session.hash_key

in the example in the question to test that Session() provides the same session in two calls if and only if both were made in the same thread.

So in summary, the sessions are linked properly to the requests as long as every request is handled by its own thread.

Upvotes: 3

Related Questions