【问题标题】:sqlalchemy: Why create a sessionmaker before assign it to a Session object?sqlalchemy:为什么在将 sessionmaker 分配给 Session 对象之前创建它?
【发布时间】:2013-03-22 22:44:09
【问题描述】:

为什么我总是需要在 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()

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

import sqlalchemy as sa
import sqlalchemy.orm as orm

engine = sa.create_engine(<dbPath>, echo=True)
Session = orm.Session(bind=engine)

【问题讨论】:

    标签: python session orm sqlalchemy


    【解决方案1】:

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

    session = sessionmaker(expire_on_commit=False)
    

    但是稍后,当您知道您正在与哪个数据库通信时,您可以为其添加配置:

    session.configure(bind=create_engine("some engine"))
    

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

    session = scoped_session(sessionmaker(bind=engine))
    

    综上所述,这些只是文档引用的约定,以便呈现一致的“如何使用”故事。如果这样更方便,你没有理由不能直接使用构造函数,我一直使用Session() 构造函数。只是在一个非平凡的应用程序中,无论如何,您可能最终会将构造函数调用坚持到某种可调用函数中的Session(),sessionmaker() 作为该可调用函数的默认值。

    【讨论】:

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

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

    尝试pprint,看看里面有什么;

    import pprint
    pprint.pprint(my_session)
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多