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