[Sqlalchemy-tickets] Issue #3145: AttributeError: 'NoneType' object has no attribute '_sa_appender'
Brought to you by:
zzzeek
|
From: Dobes V. <iss...@bi...> - 2014-07-29 23:31:55
|
New issue 3145: AttributeError: 'NoneType' object has no attribute '_sa_appender' https://bitbucket.org/zzzeek/sqlalchemy/issue/3145/attributeerror-nonetype-object-has-no Dobes Vandermeer: Under certain circumstances the above error can occur. It's a bit hard to explain, but I will try. In our case: 1. An entity joins to itself in a parent/child relation 2. An instance has its parent relation set to itself 3. A collection in the parent entity is eagerly loaded as part of a query 4. The properties of the entity are ordered such that the collection is loaded after the parent This triggers a sequence of events in which: 1. The child is loaded 2. The parent is loaded (which is actually the child) as part of loading properties 3. The parent initializes the collection for eager loading 4. The child continues setting up its properties, setting the same collection to the default (lazy loaded) collection 5. The collection set up in the parent to collect the eagerly loaded entities is garbage collected 6. When a member of the collection is loaded on a subsequent row, there is a crash because the underlying collection was garbage collected The stack trace is as follows: ``` #!python Traceback (most recent call last): File "/home/dobes/sqlalchemy/test/orm/test_temp.py", line 62, in test_bug res = session.query(A).join(A.b).join(b_parent, b_parent.b_id == B.parent_id).join(b_parent.z).filter(BC.value>0).options(joinedload('b').joinedload('parent').joinedload('z').joinedload('c')).all() File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/query.py", line 2300, in all return list(self) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/loading.py", line 73, in instances rows = [process[0](row, None) for row in fetch] File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/loading.py", line 455, in _instance populate_state(state, dict_, row, isnew, only_load_props) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/loading.py", line 305, in populate_state populator(state, dict_, row) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/strategies.py", line 1483, in load_scalar_from_joined_existing_row existing = _instance(row, None) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/loading.py", line 484, in _instance populate_state(state, dict_, row, isnew, attrs) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/loading.py", line 309, in populate_state populator(state, dict_, row) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/strategies.py", line 1483, in load_scalar_from_joined_existing_row existing = _instance(row, None) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/loading.py", line 484, in _instance populate_state(state, dict_, row, isnew, attrs) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/loading.py", line 309, in populate_state populator(state, dict_, row) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/strategies.py", line 1465, in load_collection_from_joined_existing_row _instance(row, result_list) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/loading.py", line 503, in _instance result.append(instance) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/util/_collections.py", line 757, in append self._data_appender(item) File "/home/dobes/sqlalchemy/test/../lib/sqlalchemy/orm/collections.py", line 657, in append_without_event self._data()._sa_appender(item, _sa_initiator=False) AttributeError: 'NoneType' object has no attribute '_sa_appender' ``` I've attached a test case that reproduces the issue. Note that because the order of properties is significant, I did a bit of a hack to sort the properties. |