【问题标题】:Difference between Sqlalchemy scoped_session(..) and scoped_session(..)()Sqlalchemy scoped_session(..) 和 scoped_session(..)() 之间的区别
【发布时间】:2016-09-29 02:51:51
【问题描述】:

显式使用scoped_session有什么区别:

engine = create_engine(url)
session = scoped_session(sessionmaker(bind=engine))

session.add(..)
session.commit()
session.remove()

session.add(..)
session.commit()
session.remove()

并创建scoped_session 对象的实例:

engine = create_engine(url)
session = scoped_session(sessionmaker(bind=engine))

session().add(..)
session().commit()
session.remove()

session().add(..)
session().commit()
session.remove()

Sqlachemy 总是通过调用session() 为同一个线程返回同一个会话:

>> session() is session() 
True
>> session is session() 
False

这是在多线程环境中操作连接的正确方法吗?如果是这样,为什么 sqlalchemy 允许使用 session 而不是 session() 进行查询?

【问题讨论】:

    标签: sqlalchemy


    【解决方案1】:

    “scoped_session”返回一个工厂对象,所以你必须调用工厂返回一个实例。当从同一个作用域调用时,“scoped_session”实际上会返回同一个会话(在几乎每个用例中,作用域都是单个用户对网页的请求)。

    因此,尽管您反复调用 session(),但实际上并没有创建多个会话,而是每次都返回同一个会话。

    我建议使用大写的 S 来表示 session 是工厂而不是对象的实例。

    这里有更多文档,比我做的更详细:http://docs.sqlalchemy.org/en/latest/orm/contextual.html

    编辑:两种方式都将访问同一个对象。我一直发现从 scoped_session 生成实例更清楚(并非所有工厂都提供这样的功能),但两者都将访问线程本地会话对象。

    http://docs.sqlalchemy.org/en/latest/orm/contextual.html#implicit-method-access

    【讨论】:

    • 小心术语。 Python 中的生成器是一个非常特殊的东西。 “工厂”就是你所说的。
    • ""scoped_session" 返回一个生成器对象,因此您必须调用生成器来返回一个实例" - 最好的部分是我不必这样做,因为两者都有效:Session.commit() 和 @987654324 @。问题是,有什么区别?也许Session().commit() 在多线程中工作,而Session.commit() 不是?
    • 更新了我的答案。基本上,工厂将自动返回正确的线程本地会话。我发现这个功能不清楚,但每个人都有。
    猜你喜欢
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 2011-09-25
    • 2013-08-27
    • 1970-01-01
    • 2010-11-24
    相关资源
    最近更新 更多