ObjectDeletedError on orm.Query.delete

62 views
Skip to first unread message

Yang Zhang

unread,
Jul 1, 2010, 9:40:46 PM7/1/10
to sqlal...@googlegroups.com
We're getting a strange ObjectDeletedError that we've been trying to
debug for a large part of the day. The problem occurs when we keep a
(hard) reference to an ORM object, drop_all, create_all, then delete()
on a query over that ORM class (using the same scoped_session).
Unfortunately, just the above steps aren't enough; despite our efforts
so far, we haven't been able to reproduce this outside of our (large)
application. Any help would be tremendously appreciated.

Traceback (most recent call last):
...
File "/home/yang/work/app.py", line 3115, in foo
count = q.delete()
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/query.py",
line 1858, in delete
if issubclass(cls, target_cls) and eval_condition(obj)]
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/evaluator.py",
line 60, in evaluate
value = sub_evaluate(obj)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/evaluator.py",
line 60, in evaluate
value = sub_evaluate(obj)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/evaluator.py",
line 60, in evaluate
value = sub_evaluate(obj)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/evaluator.py",
line 60, in evaluate
value = sub_evaluate(obj)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/evaluator.py",
line 60, in evaluate
value = sub_evaluate(obj)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/evaluator.py",
line 60, in evaluate
value = sub_evaluate(obj)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/evaluator.py",
line 60, in evaluate
value = sub_evaluate(obj)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/evaluator.py",
line 82, in evaluate
left_val = eval_left(obj)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/evaluator.py",
line 42, in <lambda>
return lambda obj: get_corresponding_attr(obj)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/attributes.py",
line 159, in __get__
return self.impl.get(instance_state(instance), instance_dict(instance))
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/attributes.py",
line 377, in get
value = callable_(passive=passive)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/state.py",
line 268, in __call__
self.manager.deferred_scalar_loader(self, toload)
File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/mapper.py",
line 2097, in _load_scalar_attributes
raise orm_exc.ObjectDeletedError("Instance '%s' has been deleted."
% state_str(state))
ObjectDeletedError: Instance '<Blah at 0x33032d0>' has been deleted.

When echoing the SQL, we see toward the end:

...
sqlalchemy.engine.base.Engine.0x...1f90: INFO: DELETE FROM blah WHERE
blah.actor_id = ? AND blah.atype = ? AND blah.domain = ? AND ...
sqlalchemy.engine.base.Engine.0x...1f90: INFO: (<read-only buffer for
0x4aaece0, size -1, offset 0 at 0x4807170>, 2, u'fake.com', ...)
sqlalchemy.engine.base.Engine.0x...1f90: INFO: SELECT blah.id AS
blah_id, blah.actor_id AS blah_actor_id, blah.domain AS blah_domain,
...
FROM blah
WHERE blah.id = ?
sqlalchemy.engine.base.Engine.0x...1f90: INFO: (426,)
sqlalchemy.engine.base.Engine.0x...1f90: INFO: ROLLBACK
--
Yang Zhang
http://yz.mit.edu/

Michael Bayer

unread,
Jul 1, 2010, 9:53:18 PM7/1/10
to sqlal...@googlegroups.com

On Jul 1, 2010, at 9:40 PM, Yang Zhang wrote:

> We're getting a strange ObjectDeletedError that we've been trying to
> debug for a large part of the day. The problem occurs when we keep a
> (hard) reference to an ORM object, drop_all, create_all, then delete()
> on a query over that ORM class (using the same scoped_session).
> Unfortunately, just the above steps aren't enough; despite our efforts
> so far, we haven't been able to reproduce this outside of our (large)
> application. Any help would be tremendously appreciated.


The object you're holding onto previously is no longer valid. You're dropping all the tables in between, the row is gone. If that old object gets involved in a new session, an attribute gets hit, it goes to the database to refresh, and that's the error you get. In this case it seems that your delete() is seeing that the old object, present in the session, is part of what would have been deleted, and seeks to mark it as "deleted"- but it's state is incongruent with the changes that have occurred without the Session's knowledge.

ORM loaded objects contain state which link them to the row they originated from.

There's any number of options to proceed here. You could send the correct arguments to your delete() such that the evaluator isn't used. You could prevent the old object from being expired. You could manipulate the state of the old object or remove it from the session. The best option of all would be, if you're dropping tables, you definitely should be closing out all Sessions beforehand - what you're doing here doesn't make any sense.

> --
> You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
> To post to this group, send email to sqlal...@googlegroups.com.
> To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
>

Reply all
Reply to author
Forward
0 new messages