如何防止在 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 "nnInstance %s being updatednn" % target
    object_session(target).expunge(target)

编辑 1:

@event.listens_for(Walrus, 'before_update', raw=True)
def prevent_walrus_update(mapper, connection, target):
    print "nnInstance %s being updatednn" % target
    if target not None:
        raise
@event.listens_for(Boot, 'before_delete', raw=True)
def prevent_boot_delete(mapper, connection, target):
    print "nnInstance %s being deletednn" % target
    if target not None:
        raise

我已经让它在不允许我对海象进行更新或删除 Boot 的地方工作,但任何尝试尝试的提示都会因我似乎没有任何能力捕捉的 AttributeError 而崩溃。例如,如果我运行 Walrus1.name = "Josh",然后以 al(即使是 get)进行任何查询,则 AttributeError 都会使应用程序崩溃。我比以前走得更远,但仍然很不方便。

如果您只是将循环更改为:

for obj in thissession.dirty:

您可以使用相同的 before_flush 事件通过循环访问 thissession.deleted 来防止删除 Boot 对象。

相关内容

  • 没有找到相关文章

最新更新