python:如何获取mysql数据库更改的通知?
在Python中,有没有办法知道MySQL数据库中的某个特定表发生了变化?
5 个回答
是的,这可能不是SQL的标准。不过,自从大约9.x版本开始,PostgreSQL就支持这个功能,使用的是LISTEN和NOTIFY。
如果你说的“改变”是指一行数据被更新、删除或插入,那么有一种解决办法。
你可以在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()
调用的命令行工具连接起来。
不推荐这样做
这种做法不太推荐,因为可能会导致:
- 让MySQL变慢;
- 如果my_cmd没有返回,可能会导致系统挂起或超时;
- 如果你在使用事务,你会在事务结束之前收到通知;
- 如果事务回滚,我不确定你是否会收到
delete
的通知; - 这个设计很糟糕。
相关链接
sys_exec: http://www.mysqludf.org/lib_mysqludf_sys/index.php
理论上这是可行的,但我不推荐这样做:
简单来说,你可以在表上设置一个触发器,它会调用一个用户定义的函数(UDF),这个函数会以某种方式和你的Python应用程序进行通信。
但是,这里有一些问题需要注意:如果出现错误会怎样?
如果它被阻塞了呢?触发器内部发生的任何事情最好是能立即完成。
如果它在一个事务中,而这个事务被回滚了呢?
我相信还有很多其他问题我没有想到。
如果可能的话,更好的方法是让你的数据访问层通知应用程序的其他部分。如果你想知道一个你无法控制的程序何时修改了数据库,那可能就没办法了。
还有一种不太理想但我认为比在触发器中调用另一个程序更好的方法,就是设置一个“最后修改时间”的表,这个表会通过触发器进行更新。然后在你的应用程序中,只需检查这个时间是否晚于你上次检查的时间。