2011-06-29 40 views
23

我在我的web項目中使用SQlAlchemy。我應該使用scoped_session(session_maker())或普通session_maker()以及爲什麼?或者我應該使用別的東西?scoped_session(session_maker())或普通session_maker()在sqlalchemy?

## model.py 
from sqlalchemy import * 
from sqlalchemy.orm import * 

engine = create_engine('mysql://dbUser:[email protected]:dbPort/dbName', 
pool_recycle=3600, echo=False) 
metadata = MetaData(engine) 
Session = scoped_session(sessionmaker()) 
Session.configure(bind=engine) 
user = Table('user', metadata, autoload=True) 

class User(object): 
pass 

usermapper = mapper(User, user) 

## some other python file called abc.py 
from models import * 

def getalluser(): 
    session = Session() 
    session.query(User).all() 
    session.flush() 
    session.close() 

## onemore file defg.py 
from models import * 

def updateuser(): 
    session = Session() 
    session.query(User).filter(User.user_id == '4').update({User.user_lname: 'villkoo'}) 
    session.commit() 
    session.flush() 
    session.close() 

我爲每個請求創建會話=會話()對象和我關閉它。我在做正確的事情還是有更好的方法來做到這一點?

回答

20

documentation建議:提供

的scoped_session()函數,其產生會話對象的線程管理註冊表。它通常用於Web應用程序,以便可以使用單個全局變量安全地表示具有本地化爲單個線程的對象集的事務會話。

總之,使用scoped_session()來確保線程的安全性。

+1

謝謝。爲每個請求打開和關閉會話對象是否安全? – northlondoner

+4

@northlondoner,不僅是它的安全,但它的推薦方式,請參閱http://www.sqlalchemy.org/docs/orm/session.html#lifespan-of-a-contextual-session –

+5

@DanielKluev,這就是一個長的頁面,從你的評論開始已經過去了一段時間,所以也許我讀了錯誤的東西或者頁面已經改變了,但是看起來頁面看起來正好相反。對我來說,「不這樣做」的代碼示例看起來與OP代碼示例中使用的模式非常相似,其中爲每個數據庫請求創建一個新的會話。這是一個混合的術語問題(網頁請求vs數據庫請求)還是我缺少的兩個片段之間有一些區別? – mmitchell

7

Scoped_session每一個方法,因爲它會給你一個事先不能獲得的本地會話的線程(就像在模塊級別)。不需要在每個方法中打開一個新的會話,你可以使用全局會話Create僅當全局會話不可用時纔會話。即您可以編寫一種方法,返回一個會話並將其添加到包中的init .py。

+0

感謝您的寶貴答案。 – northlondoner

0

我正在尋找這個自己,但我不是專家。

我的三點是: (i)SQLAlchemy文檔根據Kluev先生的評論提供了一個使用scoped_session的建議方法,鏈接如下:http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html#using-thread-local-scope-with-web-applications。 (ii)在該網站位置,SQLAlchemy文檔還聲稱「...強烈建議使用隨Web框架提供的集成工具(如果可用),而不是scoped_session」。 (iii)例如,Flask-SQLAlchemy似乎聲稱它處理此問題:http://pythonhosted.org/Flask-SQLAlchemy/quickstart.html#a-minimal-application

+1

使用Flask-SQLAlchemy的問題是,它需要一個db.Model模型的基礎根。如果你的模型來自其他地方而不是你的web應用程序,那麼你的運氣不好。因此,需要scoped_session()。 –