- attached 490.patch
MapperExtension along Inherited mapper not properly work
See attached testcase. This test work properly if you also declare the extension on the child mapper
user_mapper = mapper(User, users, extension = ext)
admin_mapper = mapper(Admin, admins, inherits=user_mapper, extension=ext)
but in this case, the before_insert method is called twice.
Comments (6)
-
Account Deleted -
repo owner at the moment this behavior is by design. im not sure if a MapperExtension should be assumed to apply to all the child objects as well....if you look at all the methods it implements, you can see that not all of those might be desired across a whole inheritance hierarchy. im thinking id rather have the MapperExtension express if it wants to be "inherited", maybe by subclassing InheritedMapperExtension instead. what do you think ?
-
Account Deleted Yes, why not. An other way may be that a MapperExtension by default apply to all the child objects. Since 'b' inherit of 'a', everything applied to 'a' must be applied to 'b' unless that 'b' override inherited properties of a.
class AExtension(MapperExtension): def before_insert(self, mapper, connection, instance): instance.attribute = 'value' return EXT_PASS def populate_instance(self, mapper, selectcontext, row, instance, identitykey, isnew): instant.other_attribute = 'other_value' return EXT_PASS ext = AExtension() a_mapper = mapper(A, a, extension = ext) b_mapper = mapper(B, b, inherits=a_mapper) class A (object) : pass class B (A) : pass
for me, by default in that case, b_mapper must inherit the extension from a_mapper If I want to override some methods from the by default inherited mapper I can write
class BExtension(AExtension): def before_insert(self, mapper, connection, instance): return EXT_PASS b_mapper = mapper(B, b, inherits=a_mapper, extension=BExtension)
In this case, I've override the default inherited mapper by a mapper that only redefine unwanted methods. What do you think?
-
repo owner - changed milestone to 0.4.0
i propose some kind of property or method on MapperExtension, lets say
__inheritable__=True
, which will indicate the extension should propigate to inheriting mappers.just for my own notes, the steps would be along the lines of:
* compile_extensions() moves after compile_inheritance() * compile_extensions() needs to go through inherited mappers extensions (but ensuring that none are the same extension which it already has..) and add those in to its own ExtensionCarrier * ExtensionCarrier gets a "mapper" argument so it knows what mapper it was created against * ExtensionCarrier gets a method like "get_chain(somemapper)" which will return a chained MapperExtension (maybe another ExtensionCarrier object) for the given mapper, which has calculated "somemapper" against its own "mapper" and if they dont match, only returns mappers that are inheritable. this would be called at the top of `_instances` right now where it figures out the per-query extension. these chains would be cached in a dictionary based on the mapper since they need to be returned lightning fast.
-
repo owner - changed status to resolved
this is an old ticket, and I have now applied a simple fix for this in 2db36bf59c447d4d113cba0ae12f1b739c2ae923. MapperExtensions were already propagating for before/after insert/update/delete, so this rev just generalizes that change (and also increases performance).
-
repo owner - removed milestone
Removing milestone: 0.4.xx (automated comment)
- Log in to comment
patched testcase