Search code examples
pythonmultithreadingsqlalchemypython-elixir

Why does Elixir/SQLAlchemy's session.bind get set to None within threads?


I'll start with some simplified test code to demonstrate the issue I'm referencing.

t_model.py

from elixir import *

metadata.bind = 'sqlite:///test.db'
session.bind = metadata.bind

t_main.py

#!/usr/bin/python  
import t_model 
import threading 

class TestThread(threading.Thread): 
    def run(self): 
        print 'Thread ID: %s, t_model.session.bind = %s' % (threading.current_thread(), t_model.session.bind) 

class Test(object): 
    def run(self): 
        print 'Thread ID: %s, t_model.session.bind = %s' % (threading.current_thread(), t_model.session.bind) 

if __name__ == "__main__": 
    Test().run() 
    TestThread().run() 
    TestThread().start() 

The output of t_main.py:

Thread ID: <_MainThread(MainThread, started 140111907010336)>, t_model.session.bind = Engine(sqlite:///test.db)
Thread ID: <_MainThread(MainThread, started 140111907010336)>, t_model.session.bind = Engine(sqlite:///test.db)
Thread ID: <TestThread(Thread-2, started 140111865108224)>, t_model.session.bind = None

I realize that there is some under the hood work being done by Elixir/SQLAlc to instantiate new sessions for threads (I presume). I believe that is what Ants Aasma's response to this question addresses. However, why does it not carry over fields set like that? Is there a way to ensure something like that carries over?

I need the engine bound to the session so that I can make certain raw sql queries, but as soon as I instantiate a thread it forgets the value.

Any insight you guys can provide to help me understand better the legwork going on and how I might avoid having to set t_model.session.bind every time I initialize a new thread and set the engine?


Solution

  • Try replacing this:

    session.bind = metadata.bind
    

    with:

    session.configure(bind=metadata.bind)