我将从一些简化的测试代码开始,以演示我所引用的问题。
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/SQLAlc 正在做一些幕后工作来实例化线程的新会话(我想)。我相信这就是 Ants Aasma 对这个问题的回答。但是,为什么它不继承这样设置的字段呢?有没有办法确保这样的事情得以延续?
我需要绑定到会话的引擎,以便我可以进行某些原始 sql 查询,但是一旦我实例化一个线程,它就会忘记该值。
你们可以提供任何见解来帮助我更好地理解正在进行的工作以及如何避免每次初始化新线程并设置引擎时都必须设置 t_model.session.bind ?