Python sqlalchemy:为什么在将sessionmaker分配给会话对象之前创建它?

Python sqlalchemy:为什么在将sessionmaker分配给会话对象之前创建它?,python,session,orm,sqlalchemy,Python,Session,Orm,Sqlalchemy,为什么在SqlAlchemy中我总是需要分两步来做 import sqlalchemy as sa import sqlalchemy.orm as orm engine = sa.create_engine(<dbPath>, echo=True) Session = orm.sessionmaker(bind=engine) my_session = Session() 将sqlalchemy作为sa导入 将sqlalchemy.orm导入为orm 引擎=sa.创建引擎(,e

为什么在SqlAlchemy中我总是需要分两步来做

import sqlalchemy as sa
import sqlalchemy.orm as orm

engine = sa.create_engine(<dbPath>, echo=True)
Session = orm.sessionmaker(bind=engine)
my_session = Session()
将sqlalchemy作为sa导入
将sqlalchemy.orm导入为orm
引擎=sa.创建引擎(,echo=True)
Session=orm.sessionmaker(bind=engine)
我的会话=会话()
为什么我不能一蹴而就(可能更简单,不是吗?):

将sqlalchemy作为sa导入
将sqlalchemy.orm导入为orm
引擎=sa.创建引擎(,echo=True)
Session=orm.Session(bind=engine)

从最一般的意义上讲,会话建立了与数据库的所有对话,并为您在其生命周期内加载或关联的所有对象表示一个“保留区”。它提供了获取查询对象的入口点,该入口点使用会话对象的当前数据库连接将查询发送到数据库,将结果行填充到对象中,然后将这些对象存储在称为标识映射(Identity Map)的结构中,该结构维护每个对象的唯一副本,其中“唯一”表示“只有一个具有特定主键的对象”

尝试
pprint
并查看其中的内容

import pprint
pprint.pprint(my_session)

下面是故事的其余部分:

sessionmaker()存在的原因是,它所需要的各种“配置”参数只需要在一个地方设置,而不是反复重复“bind=engine、autoflush=False、expire\u on\u commit=False”等。此外,
sessionmaker()
提供了一个“可更新”的界面,您可以在应用程序中的某个位置设置它:

session = sessionmaker(expire_on_commit=False)
但稍后,当您知道您正在与哪个数据库交谈时,可以向其中添加配置:

session.configure(bind=create_engine("some engine"))
它还充当一个“可调用”来传递给非常常见的
作用域\u session()
构造:

session = scoped_session(sessionmaker(bind=engine))

尽管如此,这些只是文档中提到的约定,以便呈现一致的“如何使用”故事。如果更方便的话,没有理由不能直接使用构造函数,我一直使用
Session()
构造函数。只是在一个非平凡的应用程序中,您可能最终会在某种可调用函数中插入对
Session()
的构造函数调用,
sessionmaker()
作为该可调用函数的默认值。

当这个弹出时,我正在完成我的答案。我只是想补充一点,我曾经一直想知道&也讨厌这个。。。直到我意识到我的问题只是命名,而不是实际发生的事情。当我注意到真正发生的事情,看着引擎盖下的东西。。。这只是一个标准的工厂模式——它为my和Python节省了大量的工作。为什么不在
session=session()
上调用一次配置(不带sessionmaker),然后在需要时注入会话,而不是重复创建一个新会话来获得具有相同配置的实例?我通常认为工厂模式允许您不受特定实现的限制(例如,如果存在不同类型的会话类、BigSession、SmallSession等)。然而,在SQL alchemy中似乎只有一种类型的会话,为什么是工厂?会话是单个数据库连接上(通常)单个数据库事务的外观。它是一个有状态的对象,一次只能做一件事。大多数类型的应用程序需要同时处理任意数量的连接/事务。
session = scoped_session(sessionmaker(bind=engine))