Postgresql 监听/通知不起作用 - 只能通过在监听器上提交命令来接收通知?

问题描述 投票:0回答:1

我正在使用 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 中不起作用的过程中的一步,我想这可能是完全不同的情况。

database postgresql notify listen
1个回答
0
投票

来自文档

每次查询执行后都会收到通知。如果用户有兴趣接收通知但不想执行任何查询,则可以使用

poll()
方法来检查新消息,而不会浪费资源。

一个简单的应用程序可以不时轮询连接以检查是否有新内容到达。更好的策略是使用一些 I/O 完成函数,例如

select()
来休眠,直到连接上有一些数据要读取时被内核唤醒,从而除非有数据要读取,否则不使用 CPU:

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)
© www.soinside.com 2019 - 2024. All rights reserved.