2017-08-07 79 views
0

當讀正式SQLAlchemy的文檔,我發現下面的例子:爲什麼在SQLAlchemy中不鼓勵這種模式?

### this is the **wrong way to do it** ### 

class ThingOne(object): 
    def go(self): 
     session = Session() 
     try: 
      session.query(FooBar).update({"x": 5}) 
      session.commit() 
     except: 
      session.rollback() 
      raise 

class ThingTwo(object): 
    def go(self): 
     session = Session() 
     try: 
      session.query(Widget).update({"q": 18}) 
      session.commit() 
     except: 
      session.rollback() 
      raise 

def run_my_program(): 
    ThingOne().go() 
    ThingTwo().go() 

我真的不理解這個模式的弊端。其實我可以想到一個主要的優點:在多線程環境中,這種模式可以確保每個會話實例都是實際使用它的函數的局部變量。

有人能通過給上面的例子給出一些潛在的缺點來啓發我嗎?謝謝。

編輯:作爲多線程上下文中優點的示例。如果我們有一個Web應用程序服務器類在這裏:

class WebApp: 
    def update(self, **kwargs): 
    session = Session() 
    try:... 

這裏,頁處理器update都有自己的本地變量session,所以無論多少線程運行,它總是安全的。相反,使用另一層功能來包含session將在這種情況下引入更復雜的方式

+0

你爲什麼不引用[文檔中提出的更好的解決方案以及給出的原因](http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#when-do-i -construct-A-會話時-DO-提交 - 它和當-DO-近距它)。 –

+0

@IljaEverilä我沒有引用'Do'的例子,因爲它只顯示了一個完全相反的解決方案。所以我認爲引用一方會足以說明這個問題。即使引用了它,它仍然不清楚它給你帶來的好處。這只是一個抽象的原則來區分顧慮。但在我的情況下,我需要它絕對是線程安全的,最好不會引入另一層複雜性。 –

+0

@IljaEverilä爲什麼downvote我的問題?我試圖闡明一個不同的觀點。這不是對我們的知識庫做出的貢獻,以便更好地理解該做什麼和不該做什麼嗎? –

回答

-1

簡而言之,sqlalchemy建議會話的處理不與數據的操縱混合。正如你在下一個例子中看到的那樣。

### this is a **better** (but not the only) way to do it ### 

class ThingOne(object): 
    def go(self, session): 
     session.query(FooBar).update({"x": 5}) 

class ThingTwo(object): 
    def go(self, session): 
     session.query(Widget).update({"q": 18}) 

def run_my_program(): 
    session = Session() 
    try: 
     ThingOne().go(session) 
     ThingTwo().go(session) 

     session.commit() 
    except: 
     session.rollback() 
     raise 
    finally: 
     session.close() 

ThingOne和ThingTwo只是做這件事做CRUD,但會議的處理是那些對象之外完成。

對於多線程,會話作用域是線程本地對象。意思是說,他們不能被不同的線程共享。您可以將它們聲明爲您指定的內容,但這並不意味着從外部實體處理會話也是不好的選擇。

+0

「會話範圍」是指[範圍會話](http://docs.sqlalchemy.org/en/latest/orm/contextual.html)嗎?措辭很重要,因爲「會話範圍」意味着所有會話都具有線程本地範圍,而不是這樣。 –

相關問題