AttributeError: _data_appender on append to backref list
Here are the errors I'm seeing with 0.3.4 with appending to backref lists, in code that worked with 0.3.3:
File "(redacted)", line 162, in test_offer_interfaces
offer_resp.options.append(offer_opt)
File
"/home/jhp/work/sqlalchemy_0_3_4/lib/sqlalchemy/orm/attributes.py",
line 418, in append
self._data_appender(item)
File
"/home/jhp/work/sqlalchemy_0_3_4/lib/sqlalchemy/orm/attributes.py",
line 390, in __getattr__
return getattr(self.data, attr)
File "/home/jhp/work/sqlalchemy_0_3_4/lib/sqlalchemy/orm/query.py",
line 301, in __getattr__
raise AttributeError(key)
AttributeError: _data_appender
The relation is a normal one-many, set up using assign_mapper on the many side:
assign_mapper(CTX, OfferOption, offer_option, properties={
'offer': relation(OfferResponse, backref='options')
})
Comments (6)
-
repo owner -
reporter Looking around in pdb at the stack frames above the point of failure, something jumps out:
(Pdb) up > (redacted)/models.py(245)add_option() -> self.options.append(opt) (Pdb) self <g2b.db.models.OfferResponse object at 0x2b87f7dfdd90> (Pdb) self.options <sqlalchemy.orm.query.Query object at 0x2b87f7dfd690>
That sure doesn't look right to me -- shouldn't options there be an InstrumentedList, given the mapper relationship?
I'll try the patch in a bit -- I think it will show the same thing.
-
reporter Update, with the patch:
ArgumentError: Collection type <class 'sqlalchemy.orm.query.Query'> has no append() or add() method
I'll try to compose a simple test case this afternoon.
-
reporter Ok, I think I've tracked this down. The error is occurring because the name of the backref is 'options', which as of d1ede4c75c9c878b8678565c97b4776ffb8aa1b9 is being overwritten by assign_mapper.
I'm not sure what's the right thing to do here. I don't think assign_mapper can avoid stepping on backrefs like this one, since (I think) the backref doesn't exist when assign_mapper is monkeypatching the domain model class.
-
repo owner - changed status to resolved
workaround:
assign_mapper(CTX, OfferOption, offer_option, properties={ 'offer': relation(OfferResponse, backref=backref('options', collection_class=list)) })
added a unit test illustrating the issue in changeset:2249. when we remove class-level specification of collections, this issue will go away.
-
repo owner - removed milestone
Removing milestone: 0.3.4 (automated comment)
- Log in to comment
try this patch which will throw an error for the given data collection:
Index: lib/sqlalchemy/orm/attributes.py
--- lib/sqlalchemy/orm/attributes.py (revision 2240) +++ lib/sqlalchemy/orm/attributes.py (working copy) @@ -331,6 +331,8 @@ elif hasattr(self.data, 'add'): self._data_appender = self.data.add self._clear_data = self._clear_set + else: + raise exceptions.ArgumentError("Collection type " + repr(type(self.data)) + " has no append() or add() method") if isinstance(self.data, dict): self._clear_data = self._clear_dict