[sqlalchemy] Re: support for set/replace on a collection in AttributeExtension

2009-10-03 Thread Michael Bayer

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

2009-10-03 Thread Tomasz Jezierski - Tefnet

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

2009-10-02 Thread Michael Bayer

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
-~--~~~~--~~--~--~---