为什么Elixir/SQLAlchemy的session.bind在线程内被设为None?

1 投票
1 回答
714 浏览
提问于 2025-04-16 23:14

我先用一些简单的测试代码来说明我提到的问题。

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() 

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

我知道在背后,Elixir和SQLAlchemy正在为线程创建新的会话(我猜的)。我觉得Ants Aasma对这个问题的回答就是在讲这个。不过,为什么像这样设置的字段不被保留呢?有没有办法确保这些字段能够保留?

我需要把引擎绑定到会话上,这样我才能执行一些原始的SQL查询,但一旦我创建了一个线程,它就会忘记这个值。

你们能给我一些建议,帮助我更好地理解这些背后的工作原理,以及如何避免每次初始化新线程并设置引擎时都要重新设置t_model.session.bind吗?

1 个回答

1

试着把这个:

session.bind = metadata.bind

换成:

session.configure(bind=metadata.bind)

撰写回答