Listening for postgres NOTIFY with django.db - adding support for connection.fileno()

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Listening for postgres NOTIFY with django.db - adding support for connection.fileno()

Fábio Molinar
Hi, 

I have a custom method on my model manager that allows me to listen for notifications from modifications on the DB using postgreSQL. A short version of this code looks like this:

def listen_for_notify(self):
        import select
        import psycopg2
        import psycopg2.extensions

        from django.conf import settings
        
        db_data = settings.DATABASES['default']
        listened = None
        returned_empty = None
search_timeout = 15

        conn = psycopg2.connect(dbname=db_data['NAME'], user=db_data['USER'], password=db_data['PASSWORD'], host=db_data['HOST'], port=db_data['PORT'])
        conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
        curs = conn.cursor()
        curs.execute("LISTEN default;")

        timeout = timezone.now() + timezone.timedelta(0, search_timeout)
        while timezone.now() < timeout:
            time_diff = timeout - timezone.now()
            if select.select([conn], [], [], float(time_diff.seconds)) == ([], [], []):
                listened = False
                timeout = timezone.now()
            else:
                conn.poll()
                while conn.notifies:
                    notify = conn.notifies.pop(0)
                    if notify.payload == "notified":
                        listened = True
                        returned_empty = False
                        timeout = timezone.now()
                    if notify.payload == 'search request returned empty':
                        listened = True
                        returned_empty = True
                        timeout = timezone.now()
        curs.close()
        conn.close()
        return listened, returned_empty

It would be really nice if instead of using the psycopg2 library, I could use only django.db. Something like this:

def listen_for_notify(self):
        from django.db import connection as conn
        
        listened = None
        returned_empty = None
search_timeout = 15

        with conn.cursor() as curs
timeout = timezone.now() + timezone.timedelta(0, search_timeout)
while timezone.now() < timeout:
time_diff = timeout - timezone.now()
if select.select([conn], [], [], float(time_diff.seconds)) == ([], [], []):
listened = False
timeout = timezone.now()
else:
conn.poll()
while conn.notifies:
notify = conn.notifies.pop(0)
if notify.payload == "notified":
listened = True
returned_empty = False
timeout = timezone.now()
if notify.payload == 'search request returned empty':
listened = True
returned_empty = True
timeout = timezone.now()
        return listened, returned_empty

I tried out the solution above using django.db, but it doesn't work because the django.db.connection object don't have a fileno() method.

Is this currently not supported or am I missing something? I though that the django.db is kind of just a wrapper around the actual psycopg2 library. So I wonder why I can't use the fileno() method on it.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/b25d7b65-57d2-4547-9f3e-8ebfcb3641e6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Listening for postgres NOTIFY with django.db - adding support for connection.fileno()

Florian Apolloner
Hi,

On Monday, December 31, 2018 at 12:38:31 PM UTC+1, Fábio Molinar wrote:
Is this currently not supported or am I missing something? I though that the django.db is kind of just a wrapper around the actual psycopg2 library. So I wonder why I can't use the fileno() method on it.

django.db.connection provides a common interface for all databases, the underlying actual connection is stored as connection attribute as seen in https://github.com/django/django/blob/master/django/db/backends/base/base.py#L194 -- I hope this helps.

cheers,
Florian

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/cd615dbc-689a-4f34-84a1-6110157ee16f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Listening for postgres NOTIFY with django.db - adding support for connection.fileno()

Fábio Molinar
Thank you sir, that's what I was hoping to find! :)

Yours sincerely,

Fábio Thomaz Molinar


Em ter, 1 de jan de 2019 às 15:10, Florian Apolloner <[hidden email]> escreveu:
Hi,

On Monday, December 31, 2018 at 12:38:31 PM UTC+1, Fábio Molinar wrote:
Is this currently not supported or am I missing something? I though that the django.db is kind of just a wrapper around the actual psycopg2 library. So I wonder why I can't use the fileno() method on it.

django.db.connection provides a common interface for all databases, the underlying actual connection is stored as connection attribute as seen in https://github.com/django/django/blob/master/django/db/backends/base/base.py#L194 -- I hope this helps.

cheers,
Florian

--
You received this message because you are subscribed to a topic in the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-developers/BeugSYXeO2I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/cd615dbc-689a-4f34-84a1-6110157ee16f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAPqizwH3p%2BBL%3DVdv9L8CEcLNdd3E_j0U5eWinSqsJGKCFD-cBA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.