[sqlalchemy] Re: support for set/replace on a collection in AttributeExtension
On Oct 3, 2009, at 7:53 AM, Tomasz Jezierski - Tefnet wrote: >> >> if it were me, I'd just constrain access to a set of methods, such >> as: >> >> def set_col_attr(*values) > > We don't like polluting our namespace with useless get/set_col_attr > etc... its useful depending on your use case.I have a model here which wants to receive a whole list of items at once, and its an explicit method - since thats the one way to get items into that particular collection. If I tried to instrument behind the scenes with event handlers and whatnot and attempted to flatten foo.colllection.append() and foo.collection = bar into the same system it would be a huge mess - its the definition of explciit is better than implicit. But that's my case, not yours. In this case I went back to the original email here and looked at what you're trying to accomplish.It seems like you are just trying to create an immutable collection. > > with descriptors it will be a problem with .append .remove methods > (afaik descriptor will give us only set/get/del) so as I said you'd want to implement events for the collection as well. > >> As for events on the collection itself you can still use >> attributeextension or alternatively a custom collection class. >> > We wanted to create custom event for our attributeextension but we > don't > know how to pass our impl_class to > attributes.register_attribute_impl so > that we could use our extended CollectionAttributeImpl (with modified > _set_iterable). > > Could you suggest the best way to pass our CollectionAttributeImpl to > register_attribute_impl or maybe you can modify SQLA and allow to pass > impl_class like it is done right now with collection_class. none of that should be needed - in this case, you're just trying to build an immutable collection, so collection_class is the most appropriate way to acheive this. See the docs at http://www.sqlalchemy.org/docs/05/mappers.html#custom-collection-implementations .You can elect a private method to be the @collection.appender that the ORM will use when populating the collection from the database. All pubilc mutator methods will raise an immutable exception. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: support for set/replace on a collection in AttributeExtension
Dnia 2009-10-02, Pt o godzinie 10:49 -0400, Michael Bayer pisze: > Tefnet Developers wrote: > > > > Hi, > > > > I need to get a single event at an extension in case of such operation: > > > > obj.colAttr = [x, y, z] > > > > right now I will receive: > > extension.remove(...) for each value currently in colAttr > > extension.append(...) for x, y and z. > > > > what I need is something like: > > > > extension.replace(oldvalues, values) with two lists or something like > > that. > > > > > > > > What is the proper way to achieve this? The problem is that we want it to be as transparent as possible (should look like normal list). so.. > > if it were me, I'd just constrain access to a set of methods, such as: > > def set_col_attr(*values) We don't like polluting our namespace with useless get/set_col_attr etc... > > But if that's too simple and straightforward (sarcasm), if you want to > catch coarse-grained get/set events on a collection attribute you need > to > create your own descriptor, with the descriptor/synonym approach > described > at http://www.sqlalchemy.org/docs/05/mappers.html#using-descriptors. > That way your own descriptor can marshal access to/from the actual > attribute. with descriptors it will be a problem with .append .remove methods (afaik descriptor will give us only set/get/del) > As for events on the collection itself you can still use > attributeextension or alternatively a custom collection class. > We wanted to create custom event for our attributeextension but we don't know how to pass our impl_class to attributes.register_attribute_impl so that we could use our extended CollectionAttributeImpl (with modified _set_iterable). Could you suggest the best way to pass our CollectionAttributeImpl to register_attribute_impl or maybe you can modify SQLA and allow to pass impl_class like it is done right now with collection_class. Regards, Tomasz Jezierski Tefnet www.tefnet.pl --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: support for set/replace on a collection in AttributeExtension
Tefnet Developers wrote: > > Hi, > > I need to get a single event at an extension in case of such operation: > > obj.colAttr = [x, y, z] > > right now I will receive: > extension.remove(...) for each value currently in colAttr > extension.append(...) for x, y and z. > > what I need is something like: > > extension.replace(oldvalues, values) with two lists or something like > that. > > Right now my approach (yes, I know this is sick) is: > > def weComeFrom(): > f=inspect.currentframe().f_back.f_back > while(inspect.getmodule(f).__name__.startswith('sqlalchemy.')): > f=f.f_back > return (f.f_lasti, f.f_code) > > > class ImmutableExtension(TefAttributeExtension): > active_history = True > triggerName = 'immutable' > > def append(self, state, value, initiator): > f = weComeFrom() > try: > lf = initiator.__tefLastComeFrom > except AttributeError: > lf = None > if len(self._getOldValue(state, initiator)) == 0: > initiator.__tefLastComeFrom = f > return value > elif f == lf: > return value > else: > self.raiseError(state, value, None, initiator) > > What is the proper way to achieve this? if it were me, I'd just constrain access to a set of methods, such as: def set_col_attr(*values) But if that's too simple and straightforward (sarcasm), if you want to catch coarse-grained get/set events on a collection attribute you need to create your own descriptor, with the descriptor/synonym approach described at http://www.sqlalchemy.org/docs/05/mappers.html#using-descriptors. That way your own descriptor can marshal access to/from the actual attribute. As for events on the collection itself you can still use attributeextension or alternatively a custom collection class. > > regards, > Filip Zyzniewski > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@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 -~--~~~~--~~--~--~---