sqlalchemy-session

本文主要用來探討如何合理的使用 sqlalchemysession的一些基礎知識

session 可能遇到的問題

  • 占用連接未釋放,導致數(shù)據(jù)庫連接滿
  • 已查詢的數(shù)據(jù)使用時返回None
  • 已變更過數(shù)據(jù),但是查詢時并沒有得到最新的更新

session 是什么

  • 它管理與數(shù)據(jù)庫相關的所有操作,包括數(shù)據(jù)連接、釋放、事物相關等操作。

  • 它作為程序訪問數(shù)據(jù)庫的一個entrypoint

  • 它把從數(shù)據(jù)中取回的數(shù)據(jù)映射為ORM中的一個對象,并且存儲在一個名為Identity Map的數(shù)據(jù)結構中

  • 它在存入數(shù)據(jù)時把一個ORM對應到一個數(shù)據(jù)表

session生命周期管理

使用session的一個基本準則,一個應用應該去管理session的生命周期,對于處理特殊數(shù)據(jù)的函數(shù)session應該作為一個參數(shù)被傳遞進來并且使用。

  • 對于一個后臺任務,建議每個子線程分配一個session,生命周期為子線程生命周期
  • 對于命令行任務,建議應用建立一個單獨的全局session
  • GUI驅動的應用,建議一個用戶事件作為session的生命周期
  • 對于WEB應用,建議一個request作為生命周期

創(chuàng)建session

  • 對于sessionmaker 一般是作為一個全局變量僅定義一次
  • 對于session一般是在有數(shù)據(jù)邏輯操作開始的時候創(chuàng)建

使用session

在session中存儲了一個對象的弱引用

  • 每條數(shù)據(jù)只保留一個副本,使用主鍵識別一條數(shù)據(jù)。如果查詢時該數(shù)據(jù)已經(jīng)存在session中,查詢后將不會替換該數(shù)據(jù),除非該數(shù)據(jù)已過期。
  • 查一條數(shù)據(jù)的最新狀態(tài)時先commit再query
  • session的細節(jié),事物和異常管理盡量與程序的細節(jié)分開處理

commit&&close

  • commit 或者rollback 前每個session 代表一個事物, 在commitsession中的數(shù)據(jù)會被標記為過期,但是不會被刪除。應保證每個事物盡量短,避免持有數(shù)據(jù)鎖時間過長影響數(shù)據(jù)庫并發(fā)量。
  • 關閉session后所有的資源都會被釋放,前面說了session中的ORM都是弱引用,查詢所得的數(shù)據(jù)都可能消失。
  • 保證任務結束后關閉session防止資源泄漏,畢竟一個應用一般也就分配幾百個連接,使用完后就么有了。

session使用例子

from contextlib import contextmanager

@contextmanager
def session_scope():
    """Provide a transactional scope around a series of operations."""
    session = Session()
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()
        
        
def run_my_program():
    with session_scope() as session:
        ThingOne().go(session)
        ThingTwo().go(session)
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容