【问题标题】:python: how to get notifications for mysql database changes?python:如何获取 mysql 数据库更改的通知?
【发布时间】:2011-04-24 17:03:26
【问题描述】:

在 Python 中,有没有办法在 MySQL 数据库中的特定表发生更改时收到通知?

【问题讨论】:

    标签: python mysql


    【解决方案1】:

    理论上可行,但我不推荐:

    基本上你在桌子上有一个触发器,它调用一个 UDF,它以某种方式与你的 Python 应用程序通信。

    陷阱包括如果出现错误会发生什么?

    如果它阻塞怎么办?理想情况下,触发器内发生的任何事情都应该是近乎即时的。

    如果它在回滚的事务中怎么办?

    我敢肯定还有很多其他我没有想到的问题。

    如果可能的话,更好的方法是让您的数据访问层通知应用程序的其余部分。如果您正在寻找不受您控制的程序何时修改数据库,那么您可能不走运。

    另一种不太理想但比从触发器中调用另一个程序更好的方法是设置某种“LastModified”表,该表由带有触发器的触发器更新。然后在您的应用中检查该日期时间是否大于您上次检查的时间。

    【讨论】:

      【解决方案2】:

      如果更改是指行已被更新、删除或插入,那么有一种解决方法。

      您可以在 MySQL 中创建触发器

      DELIMITER $$
      
      CREATE TRIGGER ai_tablename_each AFTER INSERT ON tablename FOR EACH ROW
      BEGIN
        DECLARE exec_result integer;
      
        SET exec_result = sys_exec(CONCAT('my_cmd '
                                          ,'insert on table tablename '
                                          ,',id=',new.id));
        IF exec_result = 0 THEN BEGIN
          INSERT INTO table_external_result (id, tablename, result) 
            VALUES (null, 'tablename', 0)
        END; END IF;
      END$$
      
      DELIMITER ;
      

      这将调用服务器上的可执行脚本my_cmd。 (参见 sys_exec 更多信息)带有一些参数。

      my_cmd 可以是 Python 程序,也可以是您可以使用 MySQL 使用的用户帐户从命令行执行的任何程序。

      您必须为您希望程序收到通知的每个更改 (INSERT/UPDATE/DELETE) 以及每个表创建一个触发器。
      此外,您还需要找到某种方法将正在运行的 Python 程序链接到您通过 sys_exec() 调用的命令行实用程序。

      不推荐
      不推荐这种行为,因为它很可能:

      1. 降低 MySQL 速度;
      2. 如果 my_cmd 未返回,则使其挂起/超时;
      3. 如果您正在使用交易,您将在交易结束前收到通知;
      4. 我不确定如果事务回滚,您是否会收到delete 的通知;
      5. 这是一个丑陋的设计

      链接
      sys_exec: http://www.mysqludf.org/lib_mysqludf_sys/index.php

      【讨论】:

        【解决方案3】:

        是的,可能不是 SQL 标准。但是 PostgreSQL 从版本 9.x 开始就通过 LISTEN 和 NOTIFY 支持这一点

        http://www.postgresql.org/docs/9.0/static/sql-notify.html

        【讨论】:

        • 这对于 OP 来说可能不是谈论 MySQL 的选项,但对于 postgreSQL 来说是一个很好的观点,这正是我正在寻找的。​​span>
        【解决方案4】:

        标准 SQL 功能无法实现。

        【讨论】:

        • true,虽然 OP 有这个专门标记为 'mysql' 而不是 'sql'
        【解决方案5】:

        尝试使用网络监视器而不是 MySQL 触发器可能不是一个坏主意。像这样扩展网络监视器:

        http://sourceforge.net/projects/pynetmontool/

        然后编写一个脚本,等待端口 3306(或 MySQL 服务器侦听的任何端口)上的活动,然后在网络活动满足某些过滤条件时检查数据库。

        这是一个非常高级的想法,您必须进一步研究,但您不会遇到数据库触发器问题,也不必编写每秒运行的 cron 作业。

        【讨论】:

        • 想象一下,仅仅因为您在 3306 上看到了网络活动,就必须运行一个选择来查看您正在观看的数据是否发生了变化。 1. 运行选择的代码的行为本身就是网络活动在 3306 上,导致进一步选择以查看是否有任何更改。级联故障。 2. 即使您能够忽略自己的流量,任何其他表的 mysql 服务器的任何流量都会触发您的选择,从而有效地使数据库无法使用。
        猜你喜欢
        • 2021-05-03
        • 1970-01-01
        • 1970-01-01
        • 2016-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多