提交某种类型的模型后运行函数

2024-04-06

我想在实例时运行一个函数Post模型已承诺。我想运行它any他们提交的时间,所以我不想在任何地方显式调用该函数。我怎样才能做到这一点?

def notify_subscribers(post):
    """ send email to subscribers """
    ...

post = Post("Hello World", "This is my first blog entry.")
session.commit() # How to run notify_subscribers with post as argument
                 # as soon as post is committed successfully?

post.title = "Hello World!!1"
session.commit() # Run notify_subscribers once again.

无论您选择下面的哪个选项,SQLAlchemy 都会附带关于的一个重大警告after_commit event http://docs.sqlalchemy.org/en/latest/orm/events.html#sqlalchemy.orm.events.SessionEvents.after_commit(这是两种方式都发送信号的时候)。

当会话不处于活动事务中时after_commit()事件被调用,因此无法发出 SQL.

如果您的回调需要查询或提交到数据库,则可能会出现意外问题。在这种情况下,您可以使用任务队列,例如Celery http://www.celeryproject.org/在后台线程中执行此操作(使用单独的会话)。无论如何,这可能是正确的方法,因为发送电子邮件需要很长时间,并且您不希望视图在发送电子邮件时等待返回。


Flask-SQLAlchemy提供信号 http://flask-sqlalchemy.pocoo.org/dev/signals/#models_committed您可以收听发送所有插入/更新/删除操作的声音。需要通过设置来启用app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True因为跟踪修改的成本很高,并且在大多数情况下不需要。

然后监听信号:

from flask_sqlalchemy import models_committed

def notify_subscribers(app, changes):
    new_posts = [target for target, op in changes if isinstance(target, Post) and op in ('insert', 'update')]
    # notify about the new and updated posts

models_committed.connect(notify_subscribers, app)

app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True

您也可以自己实现(主要是通过从 Flask-SQLAlchemy 复制代码)。这有点棘手,因为模型更改发生在flush, 不开commit,因此您需要在刷新发生时记录所有更改,然后在提交后使用它们。

from sqlalchemy import event

class ModelChangeEvent(object):
    def __init__(self, session, *callbacks):
        self.model_changes = {}
        self.callbacks = callbacks

        event.listen(session, 'before_flush', self.record_ops)
        event.listen(session, 'before_commit', self.record_ops)
        event.listen(session, 'after_commit', self.after_commit)
        event.listen(session, 'after_rollback', self.after_rollback)

    def record_ops(self, session, flush_context=None, instances=None):
        for targets, operation in ((session.new, 'insert'), (session.dirty, 'update'), (session.deleted, 'delete')):
            for target in targets:
                state = inspect(target)
                key = state.identity_key if state.has_identity else id(target)
                self.model_changes[key] = (target, operation)

    def after_commit(self, session):
        if self._model_changes:
            changes = list(self.model_changes.values())

            for callback in self.callbacks:
                callback(changes=changes)

            self.model_changes.clear()

    def after_rollback(self, session):
        self.model_changes.clear()
def notify_subscribers(changes):
    new_posts = [target for target, op in changes if isinstance(target, Post) and op in ('insert', 'update')]
    # notify about new and updated posts

# pass all the callbacks (if you have more than notify_subscribers)
mce = ModelChangeEvent(db.session, notify_subscribers)
# or you can append more callbacks
mce.callbacks.append(my_other_callback)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

提交某种类型的模型后运行函数 的相关文章

随机推荐

  • 通过 LinkedList 实现撤消/重做功能

    我正在编写自己的 魔方 应用程序 主要班级Cube有18种旋转方式 RotateAxisXClockWise RotateAxisXAntiClockWise 顺时针旋转轴 Y 逆时针旋转轴 Y RotateAxisZClockWise R
  • 单击按钮后更改键盘布局

    我正在开发一个 Android 应用程序 并且我有一个EditText和一个二RadioButtons A and B 我想做的是 When RadioButtonA 已选中 我想更改键盘布局以使用 完成 按钮显示它 当 的时候RadioB
  • 设置电子邮件正文 HTML 格式

    我将如何让正文以 HTML 格式工作 我需要添加什么以及我需要添加哪一行 我试过 MailMessage IsBodyHtml true 但这对我不起作用 这是这样做的方法吗 该代码应该替换另一行还是应该单独占一行 using System
  • 有没有简单的方法可以在 C# 中创建方法并动态设置其主体?

    我将方法体保存在字符串中 我想动态创建方法 但我不知道 如何设置它的身体 我看到使用 CodeDom 的方式非常乏味 我看到使用 Emit 和操作码 有什么方法可以使用字符串变量中的现成代码吗 string method body retu
  • 使用 $ 和字符值动态选择数据框列

    我有一个由不同列名组成的向量 我希望能够循环每个列名以从 data frame 中提取该列 例如 考虑数据集mtcars以及一些存储在字符向量中的变量名称cols 当我尝试从中选择一个变量时mtcars使用动态子集cols 这些工作都不是
  • 主窗口关闭时 QWidget 不会关闭

    我正在尝试创建一个主窗口 QWidget 当单击按钮时它会打开一个新的 QWidget 但是当我关闭主窗口时 最近打开的 QWidget 不会关闭 main cpp QApplication a argc argv MainWindow w
  • 有没有 recaptcha v2 关闭事件?

    我用这样的代码渲染 grecaptcha let callback const p new Promise resolve gt callback result gt resolve result grecaptcha render el
  • 使用 SQL Server CTE 扁平化层次结构系列

    寻找 SQL Server CTE 示例来创建层次结构 以便我可以输出所有系列 例如展平每个层次结构 例如 在家谱中 如果根从祖父母开始 我需要每个家庭成员的层次结构列表 其中包含成员详细信息 父母的行详细信息 喜欢 child1 row
  • 模型绑定下拉选择值

    我有一个模型 该模型有一个public List
  • 使用 Python 捕获 Mac OS X 系统音频输出

    我一直在尝试使用 劫持 Mac OS X 系统音频PyAudio http people csail mit edu hubert pyaudio 并在Python中保存为wav 也就是说 我不想从麦克风等输入设备进行录制 我想获取任何或所
  • 如何防止 Visual Studio 或 Docker 更改主机端口号?

    我已经对我的 Web 应用程序进行了 Docker 化 并且可以在 Visual Studio 中运行它 但是 它选择使用的主机端口号并不一致 在哪里将其配置为始终使用相同的端口号 我发现我可以通过编辑来做到这一点launchSetting
  • GC.Collect()

    好吧 我已经读过几个有关它的主题 但就这样吧 假设我有一个应用程序 基本上我会时不时地单击一个按钮 几分钟内会发生很多事情 然后它可能会再空闲一个小时 或者可能只是一分钟 在这一切结束之后 调用 GC Collect 不是一个很好的情况吗
  • Java EE、EJB 文件处理

    我正在开发一个网络应用程序 允许用户上传图片 然后系统将为他们生成拇指 我的问题依赖于这样一个事实 EJB 可以分布在多个服务器上 因此不允许直接处理文件 我可以将图像存储在数据库中 但我希望将它们作为文件存储在其中一台服务器中 我怎样才能
  • 将 Primefaces Jar 3.3 替换为 4.0 后,primefaces 计划事件颜色不起作用

    我使用 primefaces 4 0 并尝试更改 Primefaces Lazy Schedule 中事件的颜色 因此我有以下 xhtml 代码
  • JavaScript:扩展 Array.prototype 有什么危险?

    谷歌 JavaScript 风格指南建议不要延长Array prototype https google github io styleguide jsguide html disallowed features modifying bui
  • libgdal.so.20 问题 centos rgdal

    有人可以帮我理解 rgdal 的问题是什么吗 我为centos 6 64位安装了gdal 2 但没有成功安装rgdal 我试图找出问题所在 但在互联网上没有找到任何有用的信息 这是 Rstudio 服务器控制台 install packag
  • 获取异常实例类名

    我想知道这种情况下的异常实例是什么 try some risky actions catch Exception e System out println Get instance name there 我怎样才能实现这个目标 干得好 tr
  • Angular 10:无法编写参考

    我尝试按照 Angular 更新指南从 Angular 8 升级到 Angular 10 我的项目由核心应用程序 共享 2 个库 谷歌地图和共享组件 和一个额外的 apk fsm 2 个库 应用程序及其元数据 组成 核心和共享的构建正在通过
  • 对树数据进行分组、聚合和求和的最佳方法是什么?

    给定一个自引用表 Item Id pk ParentId fk 具有关联值的相关表 ItemValue ItemId fk Amount 和一些样本数据 Item ItemValues Id ParentId ItemId Amount 1
  • 提交某种类型的模型后运行函数

    我想在实例时运行一个函数Post模型已承诺 我想运行它any他们提交的时间 所以我不想在任何地方显式调用该函数 我怎样才能做到这一点 def notify subscribers post send email to subscribers