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:
> [email protected] 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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---