There is a way to catch every modify event at the time it is being modify.

This is some code I use to send events when attribute are modified.

There is an attribute that you can put on the model class
__sa_instrumentation_manager__ = SetListener

and then here is code to handle modify events:

class ReceiveEvents(AttributeExtension):

     def set(self, obj, child, oldchild, initiator):

         key = initiator.key
         instance = obj.obj.__call__()
         obj.dict[key] = child
         if child != oldchild:
             # Attribute has been modify do something
             if hasattr(instance, '_db'):
                 instance.notify('basic_type.%s.value' % key, model=instance,
                     property=key, old=oldchild, new=child)
             else:
                 print "event: %s value %s old %s new %s" % 
(instance.__class__.__name__, key, oldchild, child)
         return obj.dict[key]

     def append(self, state, value, intiator):
         rdbm_mapper.run_created()
         return value

     def remove(self, state, value, intiator):
         rdbm_mapper.run_created()
         return value



listener = ReceiveEvents()

class SetListener(InstrumentationManager):
     def post_configure_attribute(self, class_, key, inst):
         inst.impl.extensions.insert(0, listener)


Martijn Faassen wrote:
> phrrn...@googlemail.com wrote:
>> You are correct: the code-snippet will cause an exception to be thrown
>> when SA attempts to flush any changes. However, the connection
>> callable is called *per-instance* and it is supposed to return the
>> connection to use to perform the flush. Inside the callable, you can
>> peek at the mapper and/or the instance and return whatever you deem
>> appropriate.
> 
> Ah, I see, so instances can have some say in the decision making.
> 
>> What kind of failure mode are you looking for? If you
>> have a session with forbidden writes, what should happen? Nothing gets
>> written? The legitimate updates occur but the disallowed ones generate
>> exceptions? disallowed writes are silently swallowed by a mock
>> connection (probably make programmers very upset, confused and angry!)
> 
> I think nothing at all should be committed, and an exception should be 
> raised to the application.
> 
>> The problem with any of these approches is -- as you point out -- that
>> the application is not informed of the boo-boo at the time it occurs.
>> I wonder what Michael is alluding to in his comment about implementing
>> __getattribute__? I assume he meant __setattr__?
> 
> I'm not sure, I haven't had a chance to think about it much yet.
> 
> I'd be all right if indeed the failure only occurred at the end of the 
> transaction during a commit, if at least the error message is clear. The 
> most important bit is to prevent the developer from updating a record 
> that really shouldn't be updated (instead the developer should first 
> create a new editable version of the record).
> 
> Preferable of course would be if we could do this validation earlier. 
> The validator approach in SQLAlchemy allows this, but you'd need to set 
> it manually for every mapped attribute, while I'd like to register one 
> validator for every mapped attribute...
> 
> Regards,
> 
> Martijn
> 
> 
> > 

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

Reply via email to