我的应用程序允许用户创建和删除Site
对象。我已经使用session.add()
和session.delete()
执行了此操作。然后我有'保存'和'重置'按钮,调用session.commit()
和session.rollback()
。从SQLAlchemy会话中删除一个对象,然后保存它
如果我添加一个新的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()
不会(这将确保挂起的对象可以被删除而不会出错)。
我同意Mike的说法,“删除”可以更宽容。然而,现在的情况大大简化了 - 可能有其他相关对象明确地或隐含地(通过关系)添加到同一个会话中而没有被提交。因此,IMO最简洁的方法是在会话上执行'rollback()'。 – van
谢谢,现在有道理。所以当点击删除按钮时,逻辑应该是什么?像'try:session.delete(foo);除了InvalidRequestError:session.expunge(foo)'?或者,根据[这个答案](http://stackoverflow.com/a/3897845/665488),也许:'如果has_identity(foo):session.delete(foo); else:session.expunge(foo)'? –
我可能会说“如果session.new中的对象:expunge else:delete” – zzzeek