【问题标题】:SQLAlchemy: who is in charge of the "session"? ( and how to unit-test with sessions )SQLAlchemy:谁负责“会话”? (以及如何使用会话进行单元测试)
【发布时间】:2011-02-06 09:05:45
【问题描述】:

我需要一些关于如何将 session 对象与 SQLAlchemy 一起使用以及如何组织我的映射对象的单元测试的指导。

我想做的是这样的:

thing = BigThing() # mapped object
child = thing.new_child() # create and return a related object
thing.save() # will also save the child object

为了实现这一点,我正在考虑让 BigThing 实际上将自己(和它的孩子)添加到数据库中——但这也许不是一个好主意?

尽快添加对象的一个​​原因是由数据库分配的自动id 值——它们越早可用,问题就越少(对吗?)

管理session 对象的最佳方式是什么? 谁负责session
是否应该仅在需要时创建?还是保存了很久?

我的映射对象的单元测试怎么样?...应该如何处理session? 将映射对象自动添加到数据库中是否可行?还是会带来麻烦?

【问题讨论】:

    标签: python session orm sqlalchemy unit-testing


    【解决方案1】:

    Session 就像一个存储对象的盒子。当然,您可以编写__init__ 方法来自动向其中添加对象,但这意味着它存在一些全局(唯一)会话。当然这在很多情况下会导致问题,但这也会稍微简化编写代码。这是显性与隐性的困境。有些人遵循 Python 之禅,有些人不遵循。我更喜欢指定一个盒子来明确存储。

    请注意,只要通过关系与会话中已经存在的对象相关联,就无需显式将子项添加到会话中。这就是cascading rules 的用途。默认的'save-update' 完全符合您的要求。您可能还对'all, delete-orphan' 感兴趣以实现“私有”对象,这些对象应与它们的父对象一起删除。

    我看到实现save() 方法的一些问题。在当前版本的 SQLAlchemy 中没有办法说“保存这个对象”。以前有这种能力,但从来都不可靠。 Session.flush()(从Session.commit() 调用)将所有 更改刷新到数据库。这可能是 SQLAlchemy 最烦人的特性,它阻止我在某些项目中使用它。

    单元测试非常简单(至少在您明确指定会话时),see the sample code in other question

    【讨论】:

    • 好的,我可以理解:“一盒对象”......所以它就像我一次使用的所有相关对象的容器,所有对象都在其中一起致力于数据库。我想对于单元测试,每个测试应该有一个会话。对于网络服务器,每个请求一个会话(?)。对于桌面应用程序......在应用程序的生命周期中是否只有一个会话?......或者是否应该为每个执行的“操作”创建一个新会话?完成后可以“清空盒子”并重新使用它吗?
    • 您可以对整个桌面应用程序使用单个会话,也可以对每个任务使用单独的会话。后者有点慢,但更可靠。有expunge_all()方法清除会话。
    猜你喜欢
    • 1970-01-01
    • 2018-02-11
    • 2014-05-21
    • 1970-01-01
    • 2012-09-20
    • 2020-03-20
    • 1970-01-01
    • 2012-01-21
    • 2013-05-14
    相关资源
    最近更新 更多