系列文章:html
session用於建立程序和數據庫之間的會話,全部對象的載入和保存都需經過session對象 。python
經過sessionmaker調用建立一個工廠,並關聯Engine以確保每一個session均可以使用該Engine鏈接資源:git
from sqlalchemy.orm import sessionmaker # 建立session DbSession = sessionmaker(bind=engine) session = DbSession()
session的常見操做方法包括:github
在事務處理時,需注意一下兩點:sql
Can’t reconnect until invalid transaction is rolled back
建議封裝上下文方法:數據庫
from contextlib import contextmanager @contextmanager def session_maker(session=session): try: yield session session.commit() except: session.rollback() raise finally: session.close()
調用:緩存
def update_user(): with session_maker() as db_session: db_session.query(Users).filter_by(name='test2').update({'email': 'test2@qq.com'})
session不是線程安全的,而且咱們通常session對象都是全局的,那麼在多線程狀況下,當多個線程共享一個session時,數據處理就會發生錯誤。安全
爲了保證線程安全,需使用scoped_session方法:session
db_session = scoped_session(sessionmaker(bind=engine))
session對象包含了三個重要的部分:多線程
標識映射是與ORM關聯的集合,經過標識映射保證了數據庫操做的準確性。
具體的實現原理是:維護一個Python字典(IdentityMap),關聯這個Session對象到數據庫ID的映射,當應用程序想要獲取一個session對象時,若該對象不存在,標識映射會加載該對象並緩存,若該對象已存在,則直接獲取。這樣的好處是:
一個Session對象從建立到銷燬,依次經歷四種狀態,分別是:
所謂的狀態跟蹤,就是跟蹤以上四個狀態,保證數據的準確性並在合理的時機丟棄對象以保證合理開銷,那麼具體是怎麼實現的呢?
咱們能夠看到,只有在pending狀態時,對象的內存數據和數據庫中的數據不一致,在Persistent狀態時,內存數據和數據庫數據已經一致,那麼此後任意時刻丟棄該對象數據都是能夠的,這時就須要找個合適的時機丟棄對象,過早或過晚都有其缺陷。因而,就讓垃圾回收器來作決定,在內存不夠的時候釋放對象,回收內存。
Session對象採用了弱引用機制,所謂弱引用,就是說,在保存了對象的引用的狀況下,對象仍然可能被垃圾回收器回收。在某一時刻經過引用訪問對象時,對象可能存在也可能不存在,若是對象不存在,就從新從數據庫中加載對象。而若是不但願對象被回收,只須要另外保存一個對象的強引用便可 。
session對象包括三個屬性:
三個屬性共同的特色就是內存的數據和數據庫數據不一致,也就是對象處於pending狀態,這也就代表了session保存了全部對象處於pending狀態的強引用。
以上。
代碼可參照:my github