我正在使用 Python/psycopg2 制作一个应用程序。我有一个 Postgresql 数据库,我在其中设置了一个触发器来发送有关插入/更新的通知。
它不起作用,为了调试,我设置了 2 个 Postgresql CLI,一个充当侦听器,另一个用于发送通知。我注意到,除非我通过某种命令发送,否则我不会在侦听器 CLI 上收到任何通知。例如,我将从通知 CLI 发送
NOTIFY live_data_update, 'Test notification';
,但在侦听器 CLI 上没有收到它。如果我转到侦听器 CLI,然后输入 SELECT;,然后按 Enter 键,我就会收到通知 Asynchronous notification "live_data_update" with payload "Test notification" received from server process with PID 2164
。
通知似乎位于缓冲区中,直到我通过向其发送命令来强制其刷新,但我一直在阅读的是这应该如何自动发生。
我似乎找不到其他人遇到过这个问题。需要明确的是,在侦听器上,使用我正在运行的 Postgresql CLI:
LISTEN live_data_update;
在我正在运行的通知 CLI 上:
NOTIFY live_data_update, 'Test notification';
然后我返回到侦听器 CLI(什么也看不到)并输入
SELECT;
,然后收到通知(以及 SELECT 语句的空返回)
如果有人能好心帮助我了解我可能错过的内容,我将非常感激。我被引导相信这是一种创建数据库实时反馈感的好方法,并且很乐意实现这一目标。
这只是弄清楚为什么它在 Python 中不起作用的过程中的一步,我想这可能是完全不同的情况。
来自文档:
每次查询执行后都会收到通知。如果用户有兴趣接收通知但不想执行任何查询,则可以使用
方法来检查新消息,而不会浪费资源。poll()
一个简单的应用程序可以不时轮询连接以检查是否有新内容到达。更好的策略是使用一些 I/O 完成函数,例如
来休眠,直到连接上有一些数据要读取时被内核唤醒,从而除非有数据要读取,否则不使用 CPU:select()
import select import psycopg2 import psycopg2.extensions conn = psycopg2.connect(DSN) conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) curs = conn.cursor() curs.execute("LISTEN test;") print("Waiting for notifications on channel 'test'") while True: if select.select([conn],[],[],5) == ([],[],[]): print("Timeout") else: conn.poll() while conn.notifies: notify = conn.notifies.pop(0) print("Got NOTIFY:", notify.pid, notify.channel, notify.payload)