53

我在我的网络项目中使用 SQLAlchemy。我应该使用什么 -scoped_session(sessionmaker())或简单sessionmaker()的 - 为什么?还是我应该使用其他东西?

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

engine = create_engine('mysql://dbUser:dbPassword@dbServer: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()

session = Session()我为每个请求创建一个对象并关闭它。我在做正确的事还是有更好的方法来做?

4

5 回答 5

50

推荐阅读文档

scoped_session()提供了生成对象的线程管理注册表的函数Session。它通常用于 Web 应用程序,因此可以使用单个全局变量安全地表示具有对象集的事务会话,这些对象集本地化到单个线程。

简而言之,scoped_session()用于线程安全。

于 2011-06-29T11:24:52.037 回答
10

每个方法的 Scoped_session 都会为您提供一个您无法事先获得的本地会话线程(例如在模块级别)。不需要在每个方法中打开一个新会话,您可以使用全局会话,仅当全局会话不可用。即,您可以编写一个返回会话的方法并将其添加到包内的init .py 中。

于 2011-06-29T11:41:40.250 回答
4

仅供参考,当使用 flask-sqlalchemy 时,提供的会话对象默认是一个作用域会话对象。

在此处输入图像描述

http://flask-sqlalchemy.pocoo.org/2.3/quickstart/#road-to-enlightenment

于 2019-02-12T15:36:57.153 回答
2

我自己也在研究这个,但我不是专家。

我的三点是:

  1. scoped_session根据上面 Kluev 先生的评论,SQLAlchemy 文档在此链接上提供了一种建议的方法: http ://docs.sqlalchemy.org/en/rel_0_9/orm/session.html#using-thread-local-scope-with-web -应用程序
  2. 在那个 Web 位置,SQLAlchemy 文档还说“……强烈建议使用随 Web 框架本身提供的集成工具(如果可用)而不是scoped_session.”。
  3. 例如,Flask-SQLAlchemy 似乎声称它会处理这个问题:http: //pythonhosted.org/Flask-SQLAlchemy/quickstart.html#a-minimal-application
于 2014-04-21T14:40:30.173 回答
0

不要使用 scoped_session

不要使用 Flask-SQLAlchemy

只需Session = sessionmaker()在单例/服务类中使用,并session = Session()在每个 http 请求上使用以保证提供新连接。

线程本地存储很笨拙,并且涉及保持状态,这与不同的 Web 服务器线程模型不能很好地配合。最好保持无国籍状态。例如,请参阅此处的 SqlAlchemy 文档,其中提到.remove()如果您使用的是scoped_session. 会有人记得这样做吗?

以下摘录自:https ://docs.sqlalchemy.org/en/14/orm/contextual.html#using-thread-local-scope-with-web-applications

Using the above flow, the process of integrating the Session with the web application has exactly two requirements:

-    Create a single scoped_session registry when the web application first starts, ensuring that this object is accessible by the rest of the application.

-    Ensure that scoped_session.remove() is called when the web request ends, usually by integrating with the web framework’s event system to establish an “on request end” event.

于 2021-12-05T20:50:37.513 回答