当前位置: 首页 > 知识库问答 >
问题:

在事件侦听器中创建数据库触发器

汲利
2023-03-14

我有一个烧瓶API,我使用烧瓶SQLAlChemy来处理SQLite数据库。我有一个存储日志条目的表,我想将最大行数限制为n。因为插入也是使用原始SQL从烧瓶之外的另一个脚本进行的,所以我创建了一个触发器来检查行数,如果行数高于n,则删除最旧的行数:

CREATE TRIGGER 'trigger_log_insert' 
BEFORE INSERT ON 'connection_logs' 
WHEN ( SELECT count(*) FROM  'connection_logs' ) > 5 
BEGIN 
DELETE FROM 'connection_logs' 
WHERE id NOT IN ( SELECT id FROM 'connection_logs' ORDER BY id DESC LIMIT 5 ); 
END

此触发器按预期工作,但我正在努力使用烧瓶-sqlalChemy设置它。如何设置触发器/执行原始SQL使用烧瓶sqlalChemy?SQL只需要在db创建后执行一次,所以我打算在create_all()语句后立即执行它。我偶然发现了这个StackOverflow的答案,它提出了一个显然很快就会被弃用的解决方案。我还阅读了关于自定义DDL的SQLAlChemy留档,但是我不知道如何使用flask_sqlalchemy创建这个自定义DDL。当我在SQLAlChemy留档中创建DDL时,我会收到一条错误消息,说DDL对象没有绑定到引擎或连接。

trigger = DDL(
"CREATE TRIGGER 'trigger_log_insert'"
"BEFORE INSERT ON 'connection_logs'"
"WHEN ( SELECT count(*) FROM  'connection_logs' ) > 5"
"BEGIN"
"DELETE FROM 'connection_logs' WHERE id NOT IN"
"("
"SELECT id FROM 'connection_logs' ORDER BY id DESC LIMIT 5"
");"
"END"
)

event.listen(ConnectionLog, 'after_create', trigger.execute())

我的模型是使用flask sqlalchemy的声明性基本模型定义的:

class ConnectionLog(db.Model):
    __tablename__ = 'connection_logs'

共有1个答案

符献
2023-03-14

您不需要创建DDL实例,您可以在监听器函数中执行SQL。相关的文档在这里。

import sqlalchemy as sa
...

class ConnectionLog(db.Model):
    __tablename__ = 'connection_logs'
...

def after_create(target, connection, **kw):
    connection.execute(sa.text("""\
        CREATE TRIGGER 'trigger_log_insert'
        BEFORE INSERT ON 'connection_logs'
        WHEN ( SELECT count(*) FROM  'connection_logs' ) > 5
        BEGIN
        DELETE FROM 'connection_logs' WHERE id NOT IN
        (
        SELECT id FROM 'connection_logs' ORDER BY id DESC LIMIT 5
        );
        END
        """
    ))

# Listen on the underlying table object, not on the model class.
sa.event.listen(ConnectionLog.__table__, "after_create", after_create)

确保解释器在创建表之前已阅读此代码

 类似资料:
  • 有没有办法防止事件链中的一些听众为事件开火,但允许链上的其他人开火? 比如我有这个结构 假设我已经将单击事件监听器连接到body、div#1和div#2。是否有可能在div#2事件监听器上阻止事件进入div#1或介于两者之间的任何其他监听器,并允许事件在body元素上触发? 我这样说是因为我使用谷歌地图和emberjs构建了一系列可以在地图上显示的交互式信息框。问题是ember将事件侦听器附加到b

  • 我通过infinispan缓存添加了CacheEntryExpired侦听器的n实现。addListener()方法。 侦听器事件在条目过期时激发。问题是,每次事件触发两次。 我验证(使用调试器和cache.getListeners())缓存不包含我的同一个侦听器的两个实例。getListeners的结果是: 所以只有一个听众。侦听器实现接口: 一个实现看起来像: 但是从接口中删除@CacheEn

  • 问题内容: 问候所有我想做的事情,例如触发器或侦听器(我不知道要做什么),它们将侦听特定的数据库表,并在此表上插入每个新记录后,执行一些Java代码,这意味着它检测到是否有可能插入新记录并获取其数据,我需要一些有关如何完成此过程的指南? 我正在使用Spring-Hibernate-PostgreSQL 问题答案: 这就是创建“ 侦听/提示 ”的目的。 唯一的缺点是您将需要某种类型的后台线程来定期轮

  • 我在 Azure 数据工厂中具有事件触发器,它在 Azure Blob 存储中创建新 Blob 时触发。但我的触发器在创建 Blob 时没有触发。 已按照以下链接进行操作,但卡在下面提到的点:Azure 数据工厂:事件未启动管道。 环境详情: 事件网格已注册,ADF为v2并将参数传递给管道。我的问题是我是否需要激活Azure存储事件订阅?如果是这样,我的事件处理程序应该是什么(在我的情况下是ADF

  • 问题内容: 我需要连续监视数据库行以检查更改(更新)。如果其他来源进行了某些更改或更新,则应在我的应用程序上触发该事件(我正在使用WCF)。有什么办法可以连续监听数据库行中的更改吗? 我可能拥有更多事件来监视同一表中的不同行。在性能方面有什么问题。我正在使用C#Web服务监视SQL Server后端。 问题答案: 不久前,我有一个非常相似的要求,我使用CLR SP将数据推送到消息队列中来解决了这个

  • 问题内容: 触发事件后,如何临时禁用onclick事件监听器(首选jQuery)? 例: 用户单击按钮并在下面触发此功能后,我想禁用onclick侦听器,因此不向django视图触发相同的命令。 非常感谢, 奥尔多 问题答案: 有很多方法可以做到这一点。例如: 要么 我们还可以使用事件委托来获得更清晰的代码和更好的性能: 如果执行完处理程序后不需要重新启用处理程序,则可以使用该 方法。它绑定只能执