每次调用session_maker()
都会返回一个新的session对象,两次调用返回的session对象不同。
在一个线程中,多次调用scoped_session()
返回的session对象是一个,类似单例模式。但是在不同线程中调用scoped_session()
返回的session对象是不同的。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
import time
engine = create_engine('mysql+pymysql://root:abc@140.111.223.222:3306/dbok?charset=utf8',echo=False)
session_maker = sessionmaker(bind=engine) #这是一个一般的session工厂,不能保证session对象单例,每次都会产生一个新对象。
scoped_session_maker = scoped_session(session_maker) #这是一个scoped_session工厂,在单个线程中,只产生一个session对象;线程之间保证产生的session对象不同。
import threading
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def get1(self):
return self.session1
def get2(self):
return self.session2
def run(self):
self.session1 = scoped_session_maker() #这里如果用session_maker(),下面输出全是False
self.session2 = scoped_session_maker() #这里如果用session_maker(),下面输出全是False
time.sleep(3)
def main():
th1 = MyThread()
th2 = MyThread()
th1.start()
th2.start()
time.sleep(1)
s11 = th1.get1()
s12 = th1.get2()
s21 = th2.get1()
s22 = th2.get2()
print(s11 is s12) #True,因为是一个线程
print(s11 is s21) #False,因为不同线程
print(s21 is s22) #True
main()
另外,这个scoped_session_maker
工厂还有一个remove
方法,此方法作用是让先前创建的session不再和当前线程关联,也就说在调用了scoped_session_maker.remove()
后再用scoped_session_maker()
创建的session对象和之前创建的就是不同的对象了。
主要区分其和session的close
方法。session的close
方法只会将session和数据库连接断开,让连接重回连接池。但是再创建新的session,拿到的还是原来的session。
import threading
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
_engine = create_engine('sqlite:///:memory:')
Session = scoped_session(sessionmaker(_engine))
def scoped_session_demo(remove=False):
ids = []
def push_ids():
thread_name = threading.currentThread().getName()
data = [thread_name]
data.append(Session())
if remove:
Session.remove()
data.append(Session())
ids.append(data)
t = threading.Thread(target=push_ids)
t.start()
t.join()
push_ids()
sub_thread, main_thread = ids
sub_name, sub_session_a, sub_session_b = sub_thread
main_name, main_session_a, main_session_b = main_thread
print sub_name, sub_session_a == sub_session_b
print main_name, main_session_a == main_session_b
print sub_name, '==', main_name, sub_session_a == main_session_b
print 'Without remove:'
scoped_session_demo()
print 'With remove:'
scoped_session_demo(True)
'''
Without remove:
Thread-1 True
MainThread True
Thread-1 == MainThread False
With remove:
Thread-2 False
MainThread False
Thread-2 == MainThread False
'''