2016-05-04 41 views
1

我希望通知每當一個模型被保存,然後做一些處理並保存另一個模型。我需要模型在處理階段已經有數據庫設置的ID。如何用Flask-SQLAlchemy做一個類似post_save的Django信號?

使用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=...) 

如何做SQLAlchemyFlask相似?我擡頭看ORM Events,似乎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() 

它無法在assert instance.id is not None有:

InvalidRequestError: This session is in 'committed' state; no further SQL can be emitted within this transaction. 

這可能是我只是接近這個錯誤的方式,或者我錯過了一些至關重要的事情,但我無法弄清楚。該文檔分爲FlaskFlask-SQLAlchemySQLAlchemy,我很難拼湊在一起。

我應該如何使這種後保存觸發器SQLAlchemy

回答

-1

查看this question的接受答案,它給出了使用SQLAlchemy的after_insert映射器事件的示例。它應該做你想做的,但建議使用原始SQL而不是會話對象。

1

要監聽的事件是「after_insert」,而不是「過期」:

@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異常。

相關問題