2016-05-04 2 views
1

Ich möchte jedes Mal merken, wenn ein Modell gespeichert wird und dann ein anderes Modell bearbeiten und speichern. Ich brauche das Modell, um bereits eine ID von der Datenbank in der Verarbeitungsphase festgelegt zu haben.Wie man ein Django-ähnliches post_save Signal mit Flask-SQLAlchemy macht?

Mit Django würde man überschreiben die .save() Methode des Modells oder Verwendung Signale wie:

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

Wie mit SQLAlchemy und Flask ähnlich zu tun? Ich schaute nach oben ORM Events und es schien, dass expire IntanceEvent würde die Rechnung passen. Es scheint, zu feuern, wenn ein Modellinstanz gespeichert wird, aber wenn ich versuche, die gleiche Art der Sache zu tun:

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() 

es nicht auf assert instance.id is not None mit:

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

Es könnte sein, dass ich bin nur Wenn ich mich dem falschen Weg nähere oder mir etwas Wichtiges entgeht, kann ich es nicht herausfinden. Die Dokumentation ist unter Flask, Flask-SQLAlchemy und SQLAlchemy aufgeteilt und ich habe Mühe, dies zusammen zu setzen.

Wie soll ich diese Art von Post speichern Trigger mit SQLAlchemy?

Antwort

-1

Werfen Sie einen Blick auf die akzeptierte Antwort auf this question, die ein Beispiel für die Verwendung von SQLAlchemy after_insert Mapper-Ereignis gibt. Es sollte tun, was Sie wollen, aber die Verwendung von Raw SQL anstelle von Ihrem Sitzungsobjekt wird empfohlen.

1

Das Event, das Sie hören wollen, ist ‚after_insert‘, nicht ‚verfallen‘:

@event.listens_for(MyModel, 'after_insert') 
def do_stuff(mapper, connection, target): 
    assert target.id is not None 
    ... 

Auch nach OtherModel im Inneren des Hörers zu schaffen und db.session.add Aufruf, nicht nennen db.session.commit, da es ein werfen Ausnahme.

Verwandte Themen