假设我有Dog(),Walrus(),Boot()。 我想做到这一点,所以你不能更新Walrus对象,虽然你可以删除它们,你永远不能删除Boot对象。 所以如果这样做:
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()它会在改变海象名称时抛出异常,但允许其他人改变。 如果我试图删除boot1,它会引发异常。
我已经对事件听众进行了一些刺探,但是我已经接触到的两种方式都不会让我一直在那里:
#One possibility #I don't know how to tell that it's 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's 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)编辑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我已经得到了这个工作,它不会让我对Walrus进行更新或者删除Boot,但是任何暗示我会尝试用一个AttributeError来崩溃,而这个AttributeError似乎没有什么用处。 例如,如果我运行Walrus1.name =“Josh”,然后执行任何查询,即使是get,AttributeError也会使应用程序崩溃。 我比我更进一步,但还是很不方便。
Let's say I have classes Dog(), Walrus(), Boot(). I want to make it so you cannot update Walrus objects ever although you can delete them and you can never delete Boot objects. So if do:
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()It would throw an exception on changing the walrus name but allow the others to be changed. If I tried to delete boot1 it would throw an exception.
I've taken a couple stabs at event listeners but both ways I've approached don't get me all the way there:
#One possibility #I don't know how to tell that it's 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's 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: raiseI've got this to work where it won't allow me to make updates to Walrus or deletions to Boot, but any hint at an attempt to will crash with an AttributeError that I don't seem to have any ability to catch. For example if I run Walrus1.name = "Josh" and then any query at al, even a get, an AttributeError will crash the application. I'm further along than I was, but still rather inconvenienced.
最满意答案
您发布的第一个解决方案看起来应该可行,如果您只是将环路更改为:
for obj in thissession.dirty:您可以使用相同的before_flush事件来防止通过循环thissession.deleted来删除Boot对象。
The first solution you posted looks like it should work, if you just change the loop to read:
for obj in thissession.dirty:You can use the same before_flush event to prevent deletion of Boot objects by looping through thissession.deleted.
更多推荐
发布评论