peewee Abfrage: Ein Datensatz auslesen und Fehlerresident sein wenn es keinen Datensatz gibt

Registriere dich jetzt, um exklusive Vorteile zu genießen! Als registriertes Mitglied kannst du Inhalte herunterladen und profitierst von einem werbefreien Forum.
Mach mit und werde Teil unserer Community!
  • Hallo,


    erstelle aktuell einen Telegram Bot, welchen man Fotos sendet, mit Angabe, in welcher Ordnerstruktur die Fotos abgelegt werden sollen und eine Notiz für die Fotos.

    Sind diese Informationen nicht enthalten, werden die Fotos in einer Zwischendatenbank abgelegt.

    Führt man den entsprechenden Telegram Befehl aus, dass die undefinierten Fotos verarbeitet werden, so soll der Bot die Fotos als markierte Antwort wieder vorlegen und auf die Informationen warten. Bekommt er die Informationen soll das nächste Foto verarbeitet werden, solange bis in der Zwischendatenbank keine Fotos mehr zwischen gespeichert sind.


    Da ich bei Telegram ja wieder auf Antworten warten muss etc. so funktioniert keine einfache for-Schleife über alle abgelegten Fotos. Deshalb hole ich nur einen Datensatz ab, und rufe am Ende die Funktion wieder rekrusiv auf:


    Am besten hätte mir folgender Weg gefallen um das zu realsieren:

    len() gibt es aber bei .get() nicht

    Das hatte ich aber so und so bei dieser Variante nur eingebaut, weil wenn kein Datensatz mehr in der Datenbank vorhanden ist, es zu folgendem Fehler kommt:

    Die oben gezeigte Struktur würde dann beim rekrusiv aufruf etwas anders ausseden, sonst wär eine Endlosschleife gebaut, aber das betrifft das Problem nicht...

    Wie ließe sich der auftretende Fehler db_modell.FotoUndefiniertDoesNotExist: denn gezielt mit try/except abfangen.

    das db_modell.FotoUndefiniert kommt wohl über mich zustanden

    -> db_modell = Dateiname

    -> FotoUndefiniert = Klassenname


    Da ich da keine Lösung gefunden habe, wechselte ich von get zu select


    Daher kommt auch das len(), denn wenn die Abfrage keine Datensätze enthält funktioniert alles.

    Wenn es aber Datensätze enthält, kommt es zu Problemen bei der Verarbeitung, dort wo es mit get() keine Probleme gegeben hat:

    Code
    Traceback (most recent call last):
      File "G:/Projekte/github/foto_ablage_telegrambot/fotoablage_bot.py", line 178, in <module>
        main()
      File "G:/Projekte/github/foto_ablage_telegrambot/fotoablage_bot.py", line 164, in main
        bot.undefinierte_fotos_verarbeiten("")
      File "G:/Projekte/github/foto_ablage_telegrambot/fotoablage_bot.py", line 59, in undefinierte_fotos_verarbeiten
        self.send_message(chat_id=undefiniertes_foto.chat_id,
    AttributeError: 'ModelObjectCursorWrapper' object has no attribute 'chat_id'
    
    Process finished with exit code 1


    Auch wenn ich das execute() weg lasse in der Abfrage ist es der selbe Fehler.



    Jemand eine Idee?

  • So, ich muss über das select() iterieren, dann funktioniert es.

    Auch wenn die Schleife an der Stelle ziemlich umsonst ist, es funktioniert :)


  • Hallo,


    Quote

    So, ich muss über das select() iterieren, dann funktioniert es.

    Genau. `get` ist der falsche Ansatz, weil `get` ja nur genau einen Datensatz liefert. Und wenn wäre sowie so `get_or_none` besser gewesen.


    Quote

    Auch wenn die Schleife an der Stelle ziemlich umsonst ist, es funktioniert :)

    Wieso umsonst? Das ist doch genau das, was du willst. Besser als Rekursion, weil Rekursion in Python eigentlich nie gut ist.

    Was soll denn das `break`? Ich davon würde ich Schleife denke ich so bauen:


    Code
    ...
    undefinierte_fotos = db.FotoUndefiniert.select():
    if undefinierte_fotos:
        for undefiniertes_foto in undefinierte_fotos:
            #do something
    ...

    Gruß, noisefloor

  • Hallo,


    nee, wieso? Wenn du ein Erebnis der DB-Abfrage hast, dann wird umenue zwangsläufig gleich 1. Von daher kannst du doch den ganzen `elfI umenue==1` Block mit _in_ die for-Schleife packen.


    Gruß, noisefloor

  • Ne, da hast du jetzt einen Denkfehler, denn der If Elif Block wird nur einmal abgearbeitet

    ->

    Code
    a = 1
    if a == 1:
        print(a)
        a += 1
    elif a == 2:
        print(a)
    Code
    1
    
    Process finished with exit code 0

    Somit wird zunächst die Funktion wieder verlassen, und erst wieder betreten wenn eine Antwort in Telegram gesendet worden ist und da steigt er dann im Programmblock bei umenue==1 ein.


    Und im Else Block setze ich ja auf None, nicht auf 1.


    Sofern Interesse, so sieht aktuell der Gesamtcode aus, wenn gleich wieder mit Englisch Deutsch vermischt. Iwann schaff ich das mal mir abzugewöhnen,vielleicht.


  • Hallo,


    Quote

    Ne, da hast du jetzt einen Denkfehler, denn der If Elif Block wird nur einmal abgearbeitet

    Ach so, dass ganze ist kein vorlaufender Prozess, also du _musst_ nicht das Bearbeiten eines undefinierten Fotos abschließen, wenn du dir angeben lässt, welche Fotos ohne Ordner / Text gesendet wurden?


    Warum packst du nicht die Funktionen nicht auch in die Klasse? Ich sehe da gerade keine Grund für die Trennung (wobei ich mir zugegebener Maßen den Code nicht sooo genau angeschaut habe...).


    Gruß, noisefloor

    Edited once, last by noisefloor: Zitat korrigiert ().

  • Du meinst also, die Funktion gar nicht verlassen, sondern innerhalb dieser auf die Antwort des Benutzers warten.


    Das wäre in der Tat auch eine Möglichkeit.

    Aktuell verlässt er seinen "Menüpunkt" (Funktion) wieder, und speichert aktuelles Menü und Untermenü in den Attributen menue und umenue zwischen. Bei einer neuen Antwort weiß somit das Programm, wo es zurückkehren muss und die Nachricht an passender Stelle zu verarbeiten. Hat auch den Vorteil, dass es sich so leichter erweitern lässt, wenn es mehrere Useranfragen verarbeiten soll, wie bei meinen Wetterbot. Von da hab ich mir auch das mit menue und umenue einfallen lassen und warum von etwas bewährten abweichen :)