psycopg und select

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
PythonCodingFun
User
Beiträge: 49
Registriert: Mittwoch 22. September 2021, 14:01

Hallo liebe Commutiy,

ich möchte gerne die Python Lib psycopg verwenden, um u.a die Asynchronous notifications https://www.psycopg.org/docs/advanced.h ... ifications nutzen zu können.

Dort wird empfohlen das man select https://docs.python.org/3/library/selec ... ect.select verweden soll, wegen der CPU Zeit.

Code: Alles auswählen

connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
select.select([connection], [], [])
Aber wie kann z.b wenn das Programm läuft das select programmatisch deaktivieren, denn ich brauch nicht immer die Asynchronous notifications, ist es nicht irgendwie möglich dem Select eine Art Boolean Flag mit zu übergeben.

Mich stört es einfach das während der laufzeit das Programm im select verharrt obwohl ich die Asynchronous notifications nicht ständig benötige

Über nette Antwort würde ich mich sehr freuen :-)
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@PythonCodingFun,

mehr als das was in den verlinkten Dokumentationen steht, kenne ich leider auch nicht.
Select kann man ja anscheinend über das timeout Argument steuern. Es besteht also die Möglichkeit so lange zu warten bis Lesezugriff bereitsteht, nur für die Dauer des timeouts zu warten oder nur einmal zu "pollen". Damit stehen dir eigentlich alle Möglichkeiten offen. Im Beispiel läuft das in einer while-True-Schleife, aber es ist ja auch möglich da wieder rauszuspringen und etwas anderes zu tun.
Die innere while-Schleife wird nur durchlaufen bis alle verfügbaren Nachrichten abgeholt wurden. Also auch da besteht kein Grund immer in der Schleife zu verharren.

Daher sollte das für dich doch eigentlich funktionieren...?
PythonCodingFun
User
Beiträge: 49
Registriert: Mittwoch 22. September 2021, 14:01

rogerb hat geschrieben: Mittwoch 22. September 2021, 20:08 @PythonCodingFun,

mehr als das was in den verlinkten Dokumentationen steht, kenne ich leider auch nicht.
Select kann man ja anscheinend über das timeout Argument steuern. Es besteht also die Möglichkeit so lange zu warten bis Lesezugriff bereitsteht, nur für die Dauer des timeouts zu warten oder nur einmal zu "pollen". Damit stehen dir eigentlich alle Möglichkeiten offen. Im Beispiel läuft das in einer while-True-Schleife, aber es ist ja auch möglich da wieder rauszuspringen und etwas anderes zu tun.
Die innere while-Schleife wird nur durchlaufen bis alle verfügbaren Nachrichten abgeholt wurden. Also auch da besteht kein Grund immer in der Schleife zu verharren.

Daher sollte das für dich doch eigentlich funktionieren...?
Hallo @rogerb,

danke für deine Antwort,

mir wäre es am liebsten wenn ich es ohne Timeout machen könnte , am liebsten wäre mir wenn es mit einem Boolean ging :D
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

PythonCodingFun hat geschrieben: Mittwoch 22. September 2021, 20:59 mir wäre es am liebsten wenn ich es ohne Timeout machen könnte , am liebsten wäre mir wenn es mit einem Boolean ging :D
Tja, in der von dir verlinkten Dokumentation ist aber kein boolean als Funktionsparameter vorgesehen.

Hast du dir mal durchgelesen was für Einstellungen der timeout bewirkt? Eine Möglichkeit besteht darin nur einmal zu "pollen". Du kannst danach etwas beliebiges anderes tun. Ich kann dein Problem leider nicht nachvollziehen.

Selbst wenn du so einen boolean hättest, was sollte der denn bewirken?
LukeNukem
User
Beiträge: 232
Registriert: Mittwoch 19. Mai 2021, 03:40

rogerb hat geschrieben: Mittwoch 22. September 2021, 21:06 Selbst wenn du so einen boolean hättest, was sollte der denn bewirken?
Najaaa... also vielleicht müssen wir da unterscheiden zwischen dem SELECT in SQL und dem Systembefehl select(2)... ;-)
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Najaaa... also vielleicht müssen wir da unterscheiden zwischen dem SELECT in SQL und dem Systembefehl select(2)... ;-)
Najaaaa... also PythonCodingFun hatte ja schon klar gestellt, dass es keiner der von dir gennanten ist. SQL-SELECT hat auch nichts mit der beschriebenen Funktionalität zu tun. select(2) hat kein boolean Argument.
Daher würde ich lieber beim Thema bleiben und der Frage nachgehen, was denn dieser boolean Parameter (wenn es denn einen gäbe) für eine Funktionalität liefern sollte, die mit dem Parameter "timeout" nicht abzubilden wäre.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@LukeNukem: wie kommst Du darauf, dass der Beitrag irgend etwas mit SQL-SELECT zu tun hätte?

@PythonCodingFun: wie entscheidest Du denn, ob Du jetzt auf ein Asynchrones Ereignis warten willst, und ab wann Du nicht mehr darauf warten willst?
Willst Du nur eine bestimmte Zeit warten? Dann ist das Timeout das richtige für Dich.
Hast Du irgendein anderes Ereignis? Wie sieht dieses dann aus? Wie ist die Notification in Dein restliches Programm eingebettet?
PythonCodingFun
User
Beiträge: 49
Registriert: Mittwoch 22. September 2021, 14:01

Sirius3 hat geschrieben: Donnerstag 23. September 2021, 07:23
@PythonCodingFun: wie entscheidest Du denn, ob Du jetzt auf ein Asynchrones Ereignis warten willst, und ab wann Du nicht mehr darauf warten willst?
Willst Du nur eine bestimmte Zeit warten? Dann ist das Timeout das richtige für Dich.
Hast Du irgendein anderes Ereignis? Wie sieht dieses dann aus? Wie ist die Notification in Dein restliches Programm eingebettet?
Ich würde gerne es z.b eine Tastatureingabe steuern oder durch eine andere Methode ( eine die ein bool ausgibt so wie ein Schalter ;-) ) ohne das gesamte Programm abzuschalten, ich schreibe an einem Programm in dem ich ebendiese Funktion nicht immer brauche, sondern nur gelegentlich.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann reicht doch einfach es nicht zu machen. Wenn dein bool entsprechend gesetzt ist, dann rufst du das halt nicht auf. Warum muss select selbst das unterstützten? Tut es nun mal nicht.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@PythonCodingFun: Deine Beschreibung hilft mir nicht wirklich weiter, Dein Problem zu verstehen. Wie interagieren denn Tastatureingabe und Datenbankabfrage?
In einem normalen Programm hast Du halt eine serielle Abfolge:
1) warte auf Tastatureingabe
2) dann reagiere entsprechend der Eingabe.
3) z.B. in dem Du dann auf eine Änderung der Datenbank wartest.
4) dann kannst Du darauf reagieren
5) und eventuell wieder zu Punkt 1 springen.

Zeig doch, wie Dein Programm bisher aussieht, und wo Du konkret nicht weiterkommst.
PythonCodingFun
User
Beiträge: 49
Registriert: Mittwoch 22. September 2021, 14:01

Sirius3 hat geschrieben: Donnerstag 23. September 2021, 10:19 @PythonCodingFun: Deine Beschreibung hilft mir nicht wirklich weiter, Dein Problem zu verstehen. Wie interagieren denn Tastatureingabe und Datenbankabfrage?
In einem normalen Programm hast Du halt eine serielle Abfolge:
1) warte auf Tastatureingabe
2) dann reagiere entsprechend der Eingabe.
3) z.B. in dem Du dann auf eine Änderung der Datenbank wartest.
4) dann kannst Du darauf reagieren
5) und eventuell wieder zu Punkt 1 springen.

Zeig doch, wie Dein Programm bisher aussieht, und wo Du konkret nicht weiterkommst.
Ich nutze folgende Methode um auf einem "programmierten" Trigger in meiner PostgreSQL Datenbank zu warten select nutze ich um auf den Trigger zu "warten" ich habe es mit einem Flag kombinieren können sobald der Flag True ist und es 10 sek. keine neue Trigger Ereignisse kommen springe ich aus der while Schleife raus:

Code: Alles auswählen

import psycopg2
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
import select


def dblisten():
    connection = psycopg2.connect(
        host="127.0.0.1",
        database="DBName",
        user="postgres007",
        password="1234Passwort")

    connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
    cur = connection.cursor()
    cur.execute("LISTEN new_Id;")
    subscription = True

    while True:
        if (select.select([connection], [], [], 10) == ([], [], [])) and not subscription:
            break
        connection.poll()
        connection.commit()

        while connection.notifies:
            notify = connection.notifies.pop()
            print("Got NOTIFY:", notify.pid, notify.channel, notify.payload)


if __name__ == '__main__':
    dblisten()
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Ja, aber das ist ja ein Standalone-Programm, da hast Du ja kein Problem. Die Frage war ja, wie Du das mit Deinen anderen Funktionalitäten kombinieren willst.

`subscription` ändert sich nie, Du hast es auch falsch mit dem Timeout verbunden. Was soll denn das commit da drin?

Code: Alles auswählen

def dblisten():
    connection = psycopg2.connect(
        host="127.0.0.1",
        database="Webhook",
        user="postgres",
        password="1234567890")

    connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
    cursor = connection.cursor()
    cursor.execute("LISTEN new_Id;")

    subscription = True
    while subscription:
        if select.select([connection], [], [], 1) != ([], [], []):
            connection.poll()
            while connection.notifies:
                notify = connection.notifies.pop()
                print("Got NOTIFY:", notify.pid, notify.channel, notify.payload)
PythonCodingFun
User
Beiträge: 49
Registriert: Mittwoch 22. September 2021, 14:01

Sirius3 hat geschrieben: Donnerstag 23. September 2021, 13:49 Ja, aber das ist ja ein Standalone-Programm, da hast Du ja kein Problem. Die Frage war ja, wie Du das mit Deinen anderen Funktionalitäten kombinieren willst.

`subscription` ändert sich nie, Du hast es auch falsch mit dem Timeout verbunden. Was soll denn das commit da drin?


Aus Subscription werden eigene Methoden (getter(return boolean)/setter)
Antworten