signals or triggers in SQLAlchemy

后端 未结 5 1753
被撕碎了的回忆
被撕碎了的回忆 2021-02-04 05:04

does SQLAlchemy have something similar to Django\'s signal concept? Basically, I\'d like to trigger a few functions when I pre-save or post-save some entity objects. Thanks.

5条回答
  •  没有蜡笔的小新
    2021-02-04 05:41

    Here's my take at this problem, it uses Louie to dispatch signals:

    dispatch.py

    """
    Signals dispatching for SQLAlchemy mappers.
    """
    
    import louie
    from sqlalchemy.orm.interfaces import MapperExtension
    import signals
    
    
    class LouieDispatcherExtension(MapperExtension):
        """
        Dispatch signals using louie on insert, update and delete actions.
        """
    
        def after_insert(self, mapper, connection, instance):
            louie.send(signals.after_insert, instance.__class__,
                    instance=instance)
            return super(LouieDispatcherExtension, self).after_insert(mapper,
                    connection, instance)
    
        def after_delete(self, mapper, connection, instance):
            louie.send(signals.after_delete, instance.__class__,
                    instance=instance)
            return super(LouieDispatcherExtension, self).after_delete(mapper,
                    connection, instance)
    
        def after_update(self, mapper, connection, instance):
            louie.send(signals.after_update, instance.__class__,
                    instance=instance)
            return super(LouieDispatcherExtension, self).after_update(mapper,
                    connection, instance)
    
        def before_delete(self, mapper, connection, instance):
            louie.send(signals.before_delete, instance.__class__,
                    instance=instance)
            return super(LouieDispatcherExtension, self).before_delete(mapper,
                    connection, instance)
    
        def before_insert(self, mapper, connection, instance):
            louie.send(signals.before_insert, instance.__class__,
                    instance=instance)
            return super(LouieDispatcherExtension, self).before_insert(mapper,
                    connection, instance)
    
        def before_update(self, mapper, connection, instance):
            louie.send(signals.before_update, instance.__class__,
                    instance=instance)
            return super(LouieDispatcherExtension, self).before_update(mapper,
                    connection, instance)
    

    signals.py

    from louie import Signal
    
    
    class after_delete(Signal): pass
    class after_insert(Signal): pass
    class after_update(Signal): pass
    class before_delete(Signal): pass
    class before_insert(Signal): pass
    class before_update(Signal): pass
    

    Sample usage:

    class MyModel(DeclarativeBase):
    
        __mapper_args__ = {"extension": LouieDispatcherExtension()}
    
        ID = Column(Integer, primary_key=True)
        name = Column(String(255))
    
    def on_insert(instance):
        print "inserted %s" % instance
    
    louie.connect(on_insert, signals.after_insert, MyModel)
    

提交回复
热议问题