在SQLAlchemy会话持久化之前删除该对象

时间:2011-11-29 05:53:52

标签: python sqlalchemy

我的应用程序允许用户创建和删除Site个对象。我已使用session.add()session.delete()实现此目的。然后,我点击“保存”和“重置”按钮,调出session.commit()session.rollback()

如果我添加一个新的Site,然后保存/提交它,然后将其删除,一切正常。但是,如果我尝试在保存之前从会话中删除某个对象,则会出现“非持久性”错误。

代码:

self.newSite = Site('foo')
self.session.add(self.newSite)
print self.session.new
self.session.delete(self.newSite)

输出:

IdentitySet([<Site('foo')>])

Traceback (most recent call last):
  File "C:\Program Files\Eclipse\dropins\plugins\org.python.pydev.debug_2.2.1.2011071313\pysrc\pydevd_comm.py", line 744, in doIt
    result = pydevd_vars.evaluateExpression(self.thread_id, self.frame_id, self.expression, self.doExec)
  File "C:\Program Files\Eclipse\dropins\plugins\org.python.pydev.debug_2.2.1.2011071313\pysrc\pydevd_vars.py", line 375, in evaluateExpression
    result = eval(compiled, updated_globals, frame.f_locals)
  File "<string>", line 1, in <module>
  File "C:\Python27\Lib\site-packages\sqlalchemy\orm\session.py", line 1245, in delete
    mapperutil.state_str(state))
InvalidRequestError: Instance '<Site at 0x1ed5fb0>' is not persisted

我理解这里发生了什么,但我不确定我应该做什么。

是否有其他方法可以从会话中删除尚未持久化的对象?或者我应该在尝试删除之前调用session.flush(),以防我要删除的对象尚未刷新?

如果是后者,那么session.query()如何自动刷新(确保在查询结果中显示待处理对象),但session.delete()不会(这将确保可以删除待处理对象)没有错误)。

1 个答案:

答案 0 :(得分:15)

你可以Session.expunge()。我认为delete()就是这样的理由是,如果你把它发送到未决状态,你会担心你没有跟踪事情。但我可以看到故事的另一面,我会考虑一下。基本上delete()暗示的状态包括一些持久性的假设,但它们可能没有我想的那么重要。然后会想到一个“删除或删除”方法,这很有趣,基本上是我们最初从Hibernate复制的“保存或更新”,它刚刚成为“添加”。 “add”可以进行瞬态转换 - >挂起以及分离 - >持久 - 将潜在的“remove()”同时执行pending-&gt; transient和persistent-&gt;删除?范围内的会话已经“删除()”....

太糟糕了

Session.query()自动刷新因为它将要发送到数据库以发出一些SQL来获取一些行;所以无论你有什么在当地需要先出去。 delete()只标记对象的状态,因此不需要调用任何SQL。如果我们希望delete()处理挂起,我们只需更改该断言即可。

有趣的是,如果您rollback()会话,无论您在该会话中add()编辑了什么内容,都会被清除。