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.





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

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

Reply via email to