How can I prevent updating or deleting certain classes in SQLAlchemy?

Let's say I have classes Dog (), Walrus (), Boot (). I want to make sure that you cannot update Walrus objects, although you can delete them and you can never delete Boot objects. So if:

dog1 = Dog("DogName") walrus1 = Walrus("WalrusName") boot1 = Boot("BootName") session.add(dog1) session.add(walrus1) session.add(boot1) session.flush() transaction.commit() dog1.name = "Fluffy" walrus1.name = "Josh" boot1.name = "Pogo" session.flush() transaction.commit() 

This will throw an exception when changing the walrus name, but allow others to change. If I tried to remove boot1, it would throw an exception.

I took a couple of beats on event listeners, but both methods that I approached do not reach me:

 #One possibility #I don't know how to tell that it just an update though #The is_modified seems to take inserts as well @event.listens_for(Session, 'before_flush') def listener(thissession, flush_context, instances): for obj in thissession: if isinstance(obj, Walrus): if thissession.is_modified(obj, include_collections=False): thissession.expunge(obj) #Possiblity two #It says before_update but it seems to take in inserts as well #Also documentation says it not completely reliable to capture all statements #where an update will occur @event.listens_for(Walrus, 'before_update', raw=True) def pleasework(mapper, connection, target): print "\n\nInstance %s being updated\n\n" % target object_session(target).expunge(target) 

EDIT 1:

 @event.listens_for(Walrus, 'before_update', raw=True) def prevent_walrus_update(mapper, connection, target): print "\n\nInstance %s being updated\n\n" % target if target not None: raise @event.listens_for(Boot, 'before_delete', raw=True) def prevent_boot_delete(mapper, connection, target): print "\n\nInstance %s being deleted\n\n" % target if target not None: raise 

I got this job where it will not allow me to make walrus updates or deletes for download, but no hint of an attempt to break with AttributeError that I do not seem to have any ability to catch. For example, if I run Walrus1.name = "Josh" and then any request in al, even get, AttributeError will cause the application to crash. I'm farther than I was, but still pretty uncomfortable.

+4
source share
1 answer

The first solution you posted seems to work if you just change the loop like this:

 for obj in thissession.dirty: 

You can use the same before_flush event to prevent the removal of bootable objects by looping through thissession.deleted .

+1
source

All Articles