Python:sqlalchemy中的session

每次调用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
'''
posted @ 2018-12-26 09:27  xuejianbest  阅读(571)  评论(0编辑  收藏  举报