sessionmaker()
是一个工厂,它鼓励Session
在一个地方放置用于创建新对象的配置选项。它是可选的,因为您可以在Session(bind=engine, expire_on_commit=False)
需要新的任何时候轻松调用Session
,除了它的冗长和冗余,我想阻止小规模“帮助者”的扩散,每个帮助者都在一些新的问题中解决了这种冗余问题和更令人困惑的方式。
因此sessionmaker()
,它只是一个工具,可帮助您Session
在需要时创建对象。
下一部分。Session()
我认为问题是,在不同的点上制作一个新的与一直使用一个有什么区别。答案,不是很多。 Session
是您放入其中的所有对象的容器,然后它还跟踪打开的事务。rollback()
在您调用or的那一刻commit()
,事务已经结束,并且在Session
调用它再次发出 SQL 之前,它没有与数据库的连接。它持有的映射对象的链接是弱引用,前提是对象没有挂起的更改,因此即使在这方面,Session
当您的应用程序丢失对映射对象的所有引用时,它也会将自身清空回一个全新的状态。如果您将其保留为默认值"expire_on_commit"
设置,则所有对象在提交后都会过期。如果它Session
停留了五到二十分钟,并且下次使用它时数据库中的各种东西都发生了变化,那么下次访问这些对象时它会加载所有全新的状态,即使它们一直在内存中二十分钟。
在 Web 应用程序中,我们通常会说,嘿,为什么不对每个请求都创建一个全新Session
的,而不是一遍又一遍地使用同一个。这种做法可确保新请求开始“干净”。如果上一个请求中的一些对象还没有被垃圾回收,并且如果你已经关闭了"expire_on_commit"
,那么上一个请求中的某些状态可能仍然存在,并且那个状态甚至可能已经很老了。如果您小心地保持expire_on_commit
打开状态并确定调用commit()
或rollback()
在请求结束时,那很好,但如果您从一个全新的开始Session
,那么您甚至没有任何问题开始清洁。因此,以新的开始每个请求的想法Session
这实际上只是确保您重新开始的最简单方法,并使expire_on_commit
几乎可以选择使用,因为此标志可能会为commit()
在一系列操作中间调用的操作产生大量额外的 SQL。不确定这是否回答了您的问题。
下一轮是你提到的线程。如果您的应用程序是多线程的,我们建议确保Session
正在使用的应用程序是本地的...某物。 scoped_session()
默认情况下,它对当前线程是本地的。在 Web 应用程序中,请求的本地化实际上更好。Flask-SQLAlchemy 实际上会发送一个自定义的“范围函数”,scoped_session()
以便您获得一个请求范围的会话。普通的 Pyramid 应用程序将 Session 粘贴到“请求”注册表中。当使用这样的方案时,“在请求开始时创建新会话”的想法仍然看起来是最直接的方式来保持直截了当。