[Sqlalchemy-tickets] [sqlalchemy] #2773: error when accessing history w/ backref + make_transient o
Brought to you by:
zzzeek
|
From: sqlalchemy <mi...@zz...> - 2013-07-04 23:52:37
|
#2773: error when accessing history w/ backref + make_transient object
--------------------+------------------------------------
Reporter: zzzeek | Owner: zzzeek
Type: defect | Status: new
Priority: high | Milestone: 0.8.xx
Component: orm | Severity: major - 1-3 hours
Keywords: | Progress State: in progress
--------------------+------------------------------------
{{{
#!python
from sqlalchemy.orm import attributes, instrumentation
from sqlalchemy.testing.assertions import eq_
from mock import Mock
class Post(object):
def __init__(self, name):
self.name = name
__hash__ = None
def __eq__(self, other):
return other is not None and other.name == self.name
class Blog(object):
def __init__(self, name):
self.name = name
__hash__ = None
def __eq__(self, other):
return other is not None and other.name == self.name
lazy_posts = Mock()
instrumentation.register_class(Post)
instrumentation.register_class(Blog)
attributes.register_attribute(Post, 'blog', uselist=False,
backref='posts', trackparent=True, useobject=True)
attributes.register_attribute(Blog, 'posts', uselist=True,
backref='blog', callable_=lazy_posts, trackparent=True,
useobject=True)
lazy_posts.return_value = attributes.PASSIVE_NO_RESULT
b = Blog("blog 1")
p = Post("post 1")
state, dict_ = attributes.instance_state(b), attributes.instance_dict(b)
# this sets up NEVER_SET on b.posts
p.blog = b
eq_(state.committed_state, {"posts": attributes.NEVER_SET})
assert 'posts' not in dict_
# then suppose the object was made transient again,
# the lazy loader would return this
lazy_posts.return_value = attributes.ATTR_EMPTY
p2 = Post('asdf')
p2.blog = b
eq_(state.committed_state, {"posts": attributes.NEVER_SET})
eq_(dict_['posts'], [p2])
# then this would fail.
eq_(
Blog.posts.impl.get_history(state, dict_, passive=True),
([p2], [], [])
)
eq_(
Blog.posts.impl.get_all_pending(state, dict_),
[(attributes.instance_state(p2), p2)]
)
}}}
{{{
Traceback (most recent call last):
File "test.py", line 54, in <module>
Blog.posts.impl.get_history(state, dict_, passive=True),
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/attributes.py",
line 876, in get_history
return History.from_collection(self, state, current)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/attributes.py",
line 1345, in from_collection
for c in original
TypeError: 'symbol' object is not iterable
}}}
--
Ticket URL: <http://www.sqlalchemy.org/trac/ticket/2773>
sqlalchemy <http://www.sqlalchemy.org/>
The Database Toolkit for Python
|