[英]Sqlalchemy: Using decorator to provide thread-safe session for multiple functions
我正在研究像這里類似的東西(sqlalchemy的多線程應用程序),所以我明白,我應該為每個db-query創建一個新的會話。
我想知道,如果為每個方法使用裝飾器,需要DB訪問才有意義,或者是否有使用此方法的陷阱。 裝飾器是按照這里的最后一個例子構造的 。
def dbconnect(func):
def inner(*args, **kwargs):
session = Session() # with all the requirements
try:
func(*args, session=session, **kwargs)
session.commit()
except:
session.rollback()
raise
finally:
session.close()
return inner
@dbconnect
def some_function(some, arguments, session)
session.query(...) # no commit, close, rollback required
some_function("many", "different_arguments")
#session is not required, since provided by decorator
這樣可以很容易地為任何函數提供線程安全的DB訪問,而不需要實現整個try-except-finally-stuff冗余,但我不確定,如果這種方法是故障安全和pythonic,或者是否存在另一種最佳實踐。
我認為使用scoped_session
是scoped_session
,也許是這樣的:
session_factory = sessionmaker(bind=some_engine)
Session = scoped_session(session_factory)
def dbconnect(func):
def inner(*args, **kwargs):
session = Session() # (this is now a scoped session)
try:
func(*args, **kwargs) # No need to pass session explicitly
session.commit()
except:
session.rollback()
raise
finally:
Session.remove() # NOTE: *remove* rather than *close* here
return inner
@dbconnect
def some_function(some, arguments):
session = Session()
# 'session' is now a handle to the *same* session as in the decorator
session.query(...) # no commit, close, rollback required
some_function("many", "different_arguments")
#session is not required, since provided by decorator
(警告:未經測試)
添加參數的裝飾器很有趣,但可能很棘手。 現在定義的參數列表與調用者實際使用的內容不一致。 如果你明確地將session=something
傳遞給它,它將引發異常(盡管你可以在裝飾器中檢查它)
您還需要添加至少一個functools.wraps
(已授予,這是簡短的示例代碼)。
事務是上下文管理器的一個很好的用例。 請參閱多線程sqlalchemy webapp中推薦的scoped_session使用模式是什么? 對此有所了解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.