我有一个长时间运行的存储过程,它使用
Raise Info 'some status'
来通知客户。下面是一个虚拟函数来说明这一点:
Create or Replace Function Test_Raise() Returns void language plpgsql as $$
DECLARE
_X Text;
Begin
Raise Info 'Test 1 %', clock_timestamp();
_x = pg_sleep(2);
Raise Info 'Test 2 %', clock_timestamp();
_x = pg_sleep(10);
Raise Info 'Test 3 %', clock_timestamp();
End;$$;
在
select Test_Raise();
中调用 psql
或像 DataGrip
这样的客户端会显示执行每个 Raise
语句时的输出。使用 psycopg2 (v2.9.9),它全部显示在最后。
我已经设置了
conn.notices
和 conn.notifier
对象,这些对象显示输出会在附加内容后立即添加,并且只有 notices
属性才会生成结果,并且仅在查询完成时(它们都附加到列表中的结束)。
任何关于如何从
raise
声明中获取实时信息的建议将不胜感激。
对于那些不太了解
psycopg2
的人,这里是重现的简单代码:
import psycopg2
class Log(list):
def append(self,item):
print(item)
super().append(item)
conn = psycopg2.connect(dbname='jade_replica', host='10.158.1.63', port=32222, user='postgres', password='moozle')
conn.notifies = Log()
conn.notices = Log()
cur = conn.cursor()
cur.execute("select * from test_raise()")
原来这是
psycopg2
的限制;最好的解决方案是使用 psycopg
代替(实际上是版本 3)。它或多或少与 psycopg2
兼容,但通过 add_notice_handler
方法可以更好地处理来自服务器的异步通信。