• 数据库进阶实践-事件监听 --


    事件监听

    在flask中,我们可以使用Flask提供的过个装饰器注册请求回调函数,他们会在特定的请求处理环节被执行。类似的,SQLAlchemy也提供了一个listen_for()装饰器,他可以用来注册时间回调函数。

    listen_for()装饰器主要接收两个参数,target表示监听的对象,这个对象可以是模型类、类实例或类属性等。identifier参数表示被监听事件的标识符,比如,用于监听属性的事件标识符有set、append、remove、init_scalar、init_collection等。

    我们创建一个Draft模型类表示草稿,其中包含body字段和edit_tine字段,分别存储草稿正文和被修改的次数,其中edit_time字段的默认值为0,如下所示:

    class Draft(db.Model):
        id = db.Column(db.Integer, primary_key = True)
        body = db.Column(db.Text)
        edit_time = db.Column(db.Integer, default = 0)

    通过注册事件监听甘薯,我们可以实现在body列修改时,自动叠加表示被修改次数的edit_time字段。在SQLAlchemy中,每个事件都会有一个对应的事件方法,不同的事件方法支持不同的参数。被注册的监听函数需要接收对应事件方法的所有参数,所以具体的监听函数用法因使用的事件而异。设置某个字段值将处罚set事件。

    app.py:   set事件监听函数

    @db.event.listens_for(Draft.body, 'set')
    def increment_edit_time(target, value, oldvalue, initiator):
        if target.edit_time is not None:
            target.edit_time += 1

    我们在listen_for()装饰器中分别传入Draft.body和set作为target和identifier参数的值,监听函数接收所有set()事件方法接收的参数,其中的target参数表示触发时间的模型类实例,使用target.edit_time即可获取我们需要叠加的字段。其他的参数也需要照常写出,虽然这里没有用到。value表示被设置的值,oldvalue表示被取代的旧值。

    当set事件发生在目标对象Draft.body上时,这个监听函数就会被执行,从而自动叠加Draft.edit_time列的值,如下所示:

    >>> draft = Draft(body = 'init')
    >>> db.session.add(draft)
    >>> db.session.commit()
    >>> draft.edit_time
    0
    >>> draft.body
    u'init'
    >>> draft.body = 'edited'
    >>> draft.edit_time
    1
    >>> draft.body = 'edited again'
    >>> draft.edit_time
    2
    >>> draft.body = 'edited again again'
    >>> draft.edit_time
    3
    >>> db.session.commit()

    除了这种传统的参数接收方式,即接收所有事件方法接收的参数,还有一种更简单的方法。通过在listen_for()装饰器中将关键字参数name设为True,可以在监听函数中接收**kwargs作为参数(可变长关键字参数), 即“named argument”(命名参数)。然后在函数中可以使用参数名作为键来从**kwargs字典获取对应的参数值:

    @db.event.listens_for(Draft.body, 'set', named = True)
    def increment_edit_time(**kwargs):
        if kwargs['target'].edit_time is not None:
            kwargs['target'].edit_time += 1
    
    >>> draft = Draft.query.first()
    >>> draft
    <Draft 1>
    >>> draft.body
    u'edited again again'
    >>> draft.edit_time
    3
    >>> draft.body = 'edited 3 times'
    >>> draft.edit_time
    4

    SQLAlchemy作为SQL工具基本身包含两大主要组件:SQLAlchemy ORM和SQLAlchemy Core。前者实现了ORM功能,后者实现了数据库接口等核心功能,这两类组件都提供了大量的监听事件,几乎覆盖了SQLAlchemy使用的声明周期。

    除了使用listen_for装饰器,我们还可以直接使用它内部调用的listen()函数注册事件监听函数,第三个参数传入被注册的函数对象,比如db.event.listen(SomeClass, ‘load’, my_load_listener)。

  • 相关阅读:
    设置圆角代码
    队列组的简单使用
    多线程的延时执行和一次性代码
    GCD线程间的通信
    GCD"牛逼的中枢调度器"
    线程间的通信
    KVO运行时
    iOS Programming Localization 本地化
    iOS Programming State Restoration 状态存储
    如何安装sql server2005 windows 8
  • 原文地址:https://www.cnblogs.com/xiaxiaoxu/p/10703391.html
Copyright © 2020-2023  润新知