Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.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 如何使用炼金术完成类似Django的post_save信号?_Python_Flask_Sqlalchemy_Flask Sqlalchemy - Fatal编程技术网

Python 如何使用炼金术完成类似Django的post_save信号?

Python 如何使用炼金术完成类似Django的post_save信号?,python,flask,sqlalchemy,flask-sqlalchemy,Python,Flask,Sqlalchemy,Flask Sqlalchemy,我希望在保存一个模型时注意,然后进行一些处理并保存另一个模型。我需要模型在处理阶段已经有一个由数据库设置的ID 使用Django,可以覆盖model的.save()方法,或者使用如下信号: from django.db.models.signals import post_save from django.dispatch import receiver from .models import MyModel, OtherModel @receiver(post_save, sender=

我希望在保存一个模型时注意,然后进行一些处理并保存另一个模型。我需要模型在处理阶段已经有一个由数据库设置的ID

使用Django,可以覆盖model的
.save()
方法,或者使用如下信号:

from django.db.models.signals import post_save 
from django.dispatch import receiver

from .models import MyModel, OtherModel

@receiver(post_save, sender=MyModel)
def do_stuff(sender, instance, created, **kwargs):
    assert instance.id is not None
    ...
    OtherModel.create(related=instance, data=...)
如何使用
SQLAlchemy
Flask
进行类似操作?我抬头一看,似乎
expire
IntanceEvent符合要求。似乎每当保存模型实例时就会触发,但当我尝试执行相同的操作时:

from sqlalchemy import event

from . import db
from .models import MyModel, OtherModel

@event.listens_for(MyModel, "expire")
def do_stuff(target, attrs):
    assert target.id is not None
    ...
    db.session.add(OtherModel(related=target, data=...))
    db.session.commit()
它在断言实例时失败。id不是None,带有:

InvalidRequestError: This session is in 'committed' state; no further SQL can be emitted within this transaction.
也许我只是用错误的方式来处理这个问题,或者我遗漏了一些重要的东西,但我无法理解。文档分为
Flask
Flask-SQLAlchemy
SQLAlchemy
三部分,我很难把它们拼凑在一起


我应该如何使用
SQLAlchemy
创建这种保存后触发器?

看看公认的答案,其中给出了使用SQLAlchemy的after_insert mapper事件的示例。它应该执行您想要的操作,但建议使用原始SQL而不是会话对象。

您要侦听的事件是“插入后”,而不是“过期”:

@event.listens_for(MyModel, 'after_insert')
def do_stuff(mapper, connection, target):
    assert target.id is not None
    ...
另外,在侦听器中创建
OtherModel
并调用
db.session.add
后,不要调用
db.session.commit
,因为它将引发
ResourceClosedError
异常