sqlalchemy:为什么在将会话制作者分配给Session对象之前创建会话制作者?

use*_*431 4 python orm session 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()
Run Code Online (Sandbox Code Playgroud)

为什么我不能一次性完成(它可能更简单,不是吗?):

import sqlalchemy as sa
import sqlalchemy.orm as orm

engine = sa.create_engine(<dbPath>, echo=True)
Session = orm.Session(bind=engine)
Run Code Online (Sandbox Code Playgroud)

zzz*_*eek 8

sessionmaker()存在的原因是它需要的各种"配置"参数只需要在一个地方设置,而不是一遍又一遍地重复"bind = engine,autoflush = False,expire_on_commit = False"等.此外,sessionmaker()还提供了一个"可更新"的界面,您可以在应用程序的某个位置进行设置:

session = sessionmaker(expire_on_commit=False)
Run Code Online (Sandbox Code Playgroud)

但后来,当你知道你正在与哪个数据库交谈时,你可以添加配置:

session.configure(bind=create_engine("some engine"))
Run Code Online (Sandbox Code Playgroud)

它还可以作为"可调用"传递给非常常见的scoped_session()构造:

session = scoped_session(sessionmaker(bind=engine))
Run Code Online (Sandbox Code Playgroud)

尽管如此,这些只是文档所引用的约定,以便呈现一致的"如何使用"故事.没有理由你不能直接使用构造函数,如果这更方便,我一直使用Session()构造函数.只是在一个非平凡的应用程序中,你可能最终会将构造函数调用粘贴到Session()某种可调用函数内部,sessionmaker()作为该可调用函数的默认值.


小智 1

在最一般的意义上,会话建立与数据库的所有对话,并代表您在其生命周期内加载或与其关联的所有对象的 \xe2\x80\x9cholding zone\xe2\x80\x9d 。它提供获取 Query 对象的入口点,该对象使用 Session 对象\xe2\x80\x99s 当前数据库连接将查询发送到数据库,将结果行填充到对象中,然后存储在 Session 中,位于称为身份映射的结构内- 维护每个对象的唯一副本的数据结构,其中 \xe2\x80\x9cunique\xe2\x80\x9d 表示 \xe2\x80\x9 仅具有特定主键 \xe2\x80\x9d 的一个对象。

\n\n

尝试pprint看看里面有什么;

\n\n
import pprint\npprint.pprint(my_session)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是故事的其余部分: http://docs.sqlalchemy.org/ru/latest/orm/session.html

\n