Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在SQLAlchemy中的字段上设置事件,只有当更改涉及db时才会调用该事件_Python_Events_Sqlalchemy - Fatal编程技术网

Python 如何在SQLAlchemy中的字段上设置事件,只有当更改涉及db时才会调用该事件

Python 如何在SQLAlchemy中的字段上设置事件,只有当更改涉及db时才会调用该事件,python,events,sqlalchemy,Python,Events,Sqlalchemy,我正在使用SQLAlchemy,并且面临一个问题,当表中的一个字段发生更改时,我需要处理事件。 首先,我尝试使用文档中的代码: @listen_for(Advert.status, 'set') def handle_change_status(target, value, oldvalue, initiator): if value != oldvalue: # do smth 但此事件在字段更改时随时发生,即使我们不修改db。例如: advert=Advert()

我正在使用SQLAlchemy,并且面临一个问题,当表中的一个字段发生更改时,我需要处理事件。 首先,我尝试使用文档中的代码:

@listen_for(Advert.status, 'set')
def handle_change_status(target, value, oldvalue, initiator):
    if value != oldvalue:
         # do smth
但此事件在字段更改时随时发生,即使我们不修改db。例如:

advert=Advert()
advert.status = 3  # event apear
但我需要该事件仅在我提交更改时显示:

db.session.add(advert)
db.session.commit()  # I need event occure here
我认为我可以处理每个“set”事件并将它们写入一些存储中,然后在session.commit(在_commit之后)上添加事件,并在该事件中处理所有set事件。但这种方法似乎不是很好


可能有人有什么想法,如何解决这个问题?

所以,我用这种方式解决这个问题:

首先,我创建了init其中保存init值:

定义初始化(自):
self.\u init\u value=self.value

我还声明了一个方法,当orm从db重建对象时,该方法也会执行相同的操作:

@orm.recostructor
def初始加载(自):
self.\uuuu init\uuuuu()

然后我创建了事件:

@event.listens_for(Model, 'after_update')
def compare_old_and_new_values(mapper, connection, target):
    if target._init_value != target.value:
        # do smth

@event.listens_for(Model, 'after_insert')
def compare_old_and_new_values(mapper, connection, target):
    if target._init_value != target.value:
        # do smth
`


我认为,当多个用户更改数据库中的同一记录时,这种方法可能会有一些不当行为,但这种方法可以避免我们对数据库进行额外的SQL查询。

您能实现自定义列吗?我做这件事是为了做另一件事。但您可以使用来处理设置(进程绑定参数)是的,我可以。我是对的:我应该重写进程绑定参数方法吗?此方法是否仅在数据写入db时调用?Yes@Igor。我认为只有当值写入DB时才会调用它。您想验证值是否已更改,是吗?嗯,自定义类型无法访问旧值。我想那可能适合你。您可以在更新之前在内部发出另一个查询,以验证值是否已更改,如果另一个查询不是问题。从2019年开始。也许
@event.listens\u(SomeClass,'after\u insert')
在这里能有所帮助吗?版本1.3