Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i get PostgreSQL notifications work with python?

i was trying to follow this example from stackoverflow using pg_notify with python. I am not getting this to work. Nothing happens and python does not receive the notification.

Python 3.85 Using Psycopg2. PostgreSQL 13

python & postgresql: reliably check for updates in a specific table

First. I created a python function that listened to the postgreSQL. Then i went to pgadmin and executed

select pg_notify('process', 'update'); 

My python function is below

def dblisten(connection):
    cur = connection.cursor()
    print("inside")
    cur.execute("LISTEN process")
    while True:
        print("listening")
        select.select([connection],[],[])
        connection.poll()
        events = []
        while connection.notifies:
            notify = connection.notifies.pop().payload
            print ("Got NOTIFY:", datetime.datetime.now(), notify.pid, notify.channel, notify.payload)
if __name__ == '__main__':  # If it's executed like a script (not imported)
connection = psycopg2.connect(host='host', user='user',
                            password='password')
connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
        dblisten(connection)
like image 908
user2238704 Avatar asked Jun 14 '26 22:06

user2238704


1 Answers

I've get an error AttributeError: 'str' object has no attribute 'pid'
small fix in order to run it: notify = connection.notifies.pop().payload -> notify = connection.notifies.pop()

Here is a full example that was taken from documentation and a bit changed, it is without timeout, thanks @snakecharmerb for link listen.py

import select

import psycopg2.extensions

CHANNEL = 'process'
# DSN = f'postgresql://{USER}:{password}@{HOST}/{DBNAME}'


def listen():
    curs = conn.cursor()
    curs.execute(f"LISTEN {CHANNEL};")

    print("Waiting for notifications on channel 'test'")
    while True:
        select.select([conn], [], [], 5)
        conn.poll()
        while conn.notifies:
            notify = conn.notifies.pop(0)
            print("Got NOTIFY:", notify.pid, notify.channel, notify.payload)


if __name__ == '__main__':
    conn = psycopg2.connect(host=HOST, dbname=DBNAME, user=USER, password=PASSWD)
    # conn = psycopg2.connect(DSN) # alternative connection
    conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
    listen()
  1. Run listener python listen.py
  2. Via pgAdmin Query Tool or Postgres Shell run select pg_notify('process', 'update'); or just NOTIFY process, 'This is the payload';

note: it should be the same DB, for listener and notifier

like image 141
akpp Avatar answered Jun 17 '26 12:06

akpp