Real time notifications from a Postgres function

Question:

I am trying to execute a function in Postgres which contains a number of Raise statements for debugging and info.
While I am able to connect to DB and get raise statements using conn.notices(). These are not printed to python console on a real time basis and are only available once the function execution is complete.
Is there a way to get these notifications real time, i.e. as they are printed to the postgres log?

Update: Tried [Asynchronous Notification][1] approach replacing raise info statements with pg_notify. Even then all the notifications are printed in the console in one go.

Asked By: Rush

||

Answers:

In the RAISE case, PostgreSQL sends them in real time. You would have to dig into the guts of psycopg2 to figure out what it does with them.

I thought this would work, but I see that it doesn’t, it also saves them up until the end.

class append_printer():
  def append(self, item) -> None:
    print(item,flush=True)

conn = psycopg2.connect(...)
conn.notices=append_printer()

In the case of pg_notify, you are out of luck. By design, they are only sent once the sending transaction commits. And they are also not sent until the receiving end is between transactions.

If you upgrade to psycopg3, you can do this with a notice handler:

def log_notice(diag):
    print(f"The server says: {diag.severity} - {diag.message_primary}")

conn = psycopg.connect(...)
conn.add_notice_handler(log_notice)

prints each message as it is received.

Answered By: jjanes
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.