如何使用 Flask-SQLAlchemy 制作类似 Django 的 post_save 信号?

Sep*_*älä 5 python sqlalchemy flask flask-sqlalchemy

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

使用 Django,我们可以重写.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=...)
Run Code Online (Sandbox Code Playgroud)

如何与SQLAlchemyand做类似的事情Flask?我查了一下ORM Events,似乎expireIntanceEvent 符合要求。每当保存模型实例时它似乎都会触发,但是当我尝试做同样的事情时:

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()
Run Code Online (Sandbox Code Playgroud)

它失败了assert instance.id is not None

InvalidRequestError: This session is in 'committed' state; no further SQL can be emitted within this transaction.
Run Code Online (Sandbox Code Playgroud)

可能我只是以错误的方式处理这个问题,或者我错过了一些重要的东西,但我无法弄清楚。该文档分为FlaskFlask-SQLAlchemy并且SQLAlchemy我很难将其拼凑在一起。

我应该如何制作这种后保存触发器SQLAlchemy

Jam*_*les -1

查看此问题的已接受答案,其中给出了使用 SQLAlchemy 的 after_insert 映射器事件的示例。它应该执行您想要的操作,但建议使用原始 SQL 而不是会话对象。