2016-02-27 124 views
0

我最近開始爲我的項目使用Flask + Sqlalchemy,並在離開服務器一天後注意到500錯誤。我認爲這是由於數據庫會話超時,但我不確定。我們是否應該爲每個請求創建一個新的會話,還是Flask應用程序啓動的一個? 我有這個在我app.py燒瓶和sqlalchemy:處理會話

from sqlalchemy import Column, ForeignKey, Integer, String, create_engine, func, cast, Float 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import relationship,scoped_session,sessionmaker,aliased 
engine = createengine(DB_PATH) 
Session = sessionmaker(bind=engine) 
session = Session() 
app = Flask(name_) 

然後在視圖中的所有查詢的頂部,我做這樣的事情:「session.query(表)...」 這是錯的,應該我正在爲每個端點呼叫進行會話?

回答

0

我建議使用偉大的Flask SQLAlchemy Extension,它處理會話管理和連接池。此外,它可以根據請求處理會話的打開和關閉等。

您可以查看相關SQLAlchemy文檔以獲取更多詳細信息:http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#session-frequently-asked-questions

從文檔:

一些web框架包括基礎設施,以協助與Web請求的定向會話的壽命的任務。這包括Flask-SQLAlchemy等產品,與Flask Web框架結合使用,以及Zope-SQLAlchemy,通常與Pyramid框架一起使用。 SQLAlchemy建議將這些產品用作可用的。

2

有些情況下,使用Flask-SQLAlchemy Extension可能不合適。例如,如果您要在完全不同的Python模塊中管理模型類和數據庫連接詳細信息以便與Flask之外的軟件重用,則不需要/不需要擴展來爲您管理這些事情。

假設你有你自己的代碼來連接到數據庫,並創建通過類似的Session類(也假設engine提供):

Session = scoped_session(sessionmaker(bind=engine)) 

對於需要一個數據庫連接的頁面,您可以創建一個使用該對象的會話實例:

from flask import g 

def my_page(): 
    session = Session() 
    g.my_db_session = session # save session in the request context 
    ... 

我們需要刪除創建的會話。這需要在my_page函數結束之後,但在響應結束之前完成。以上,我們正在爲此保存會話在線程本地g對象中。要在正確的時間將其刪除,當您創建的應用程序瓶添加此代碼:

@app.teardown_appcontext 
    def shutdown_session(exception=None): 
     ''' Enable Flask to automatically remove database sessions at the 
     end of the request or when the application shuts down. 
     Ref: http://flask.pocoo.org/docs/patterns/sqlalchemy/ 
     ''' 
     if hasattr(g, 'my_db_session'): 
      g.my_db_session.remove() 

可能有其他方法可以做到這一點,但這是想法。請注意,SQLAlchemy爲您提供連接池。

+0

任何人都可以澄清一件事嗎? 「Declarative」部分的http://flask.pocoo.org/docs/0.12/patterns/sqlalchemy/中的手冊建議直接使用scoped_session返回的對象,而不是每次創建會話實例,也不要求使用g目的。哪種方法是正確的? – AlexVB