如何防止在SQLAlchemy中更新/删除特定的类?(How can I prevent specific classes from being updated/deleted in SQLAlche

编程入门 行业动态 更新时间:2024-10-28 10:27:08
如何防止在SQLAlchemy中更新/删除特定的类?(How can I prevent specific classes from being updated/deleted in SQLAlchemy?)

假设我有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: raise

I'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.

更多推荐

本文发布于:2023-04-27 14:49:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1327342.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何防止   prevent   SQLAlchemy   specific   updated

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!