asyncpg中为Pool添加PostgreSQL NOTIFY/LISTEN监听器无效的解决方法
解决asyncpg连接池使用NOTIFY/LISTEN无响应的问题
问题原因
你的代码创建连接池后没有持有活跃连接,池内的空闲连接无法主动处理PostgreSQL的通知事件,导致监听器收不到消息。另外,同步监听器函数虽能运行,但异步函数更适配asyncpg的异步模型,可避免潜在阻塞问题。
修复方案
1. 完善监听器与连接持有逻辑
修改代码,确保从连接池获取并保持一个活跃连接,同时使用异步监听器函数:
import asyncio import asyncpg async def listener(conn, channel, payload): print(f"收到通知:通道={channel},内容={payload or '无'}") async def main(): # 填写实际数据库连接参数 creds = { "host": "localhost", "user": "你的用户名", "password": "你的密码", "database": "目标数据库" } async def add_listeners(conn) -> None: print(f"为连接 {conn} 注册监听器") await conn.add_listener("listener_channel", listener) pool = await asyncpg.create_pool(**creds, setup=add_listeners) # 从连接池获取连接并保持持有,确保它能处理通知事件 async with pool.acquire() as conn: await asyncio.sleep(10000) asyncio.run(main())
2. 验证步骤
- 运行代码后,控制台输出"为连接 xxx 注册监听器",说明监听器已成功添加。
- 在PgAdmin4中执行
NOTIFY listener_channel, '测试消息';,此时控制台会打印收到的通知内容。
额外排查点
- 确认数据库连接参数完全正确,能正常连接到目标PostgreSQL实例。
- 检查当前数据库用户是否拥有
LISTEN和NOTIFY权限(默认普通用户均具备该权限)。 - 确保通道名称拼写完全一致,PostgreSQL通道名称不区分大小写,但代码中需保持统一。
内容的提问来源于stack exchange,提问作者Łukasz Kwieciński
相关产品推荐
相关产品推荐

