[Gelöst] Python3 Werte mit Variable in mariadb schreiben

  • Ich habe eine mariadb mit der Datenbank lokalerbme280 aufgesetzt und dort eine Tabelle daten.

    Dort möchte ich vier Werte vom Sensor BME280 speichern: temperatur, luftdruck, luftfeuchtigkeit und datumzeit.

    Dazu habe ich dieses Script:

    Dabei bekomme ich die Fehlermeldung:

    Code
        db.commit()
        ^
    SyntaxError: invalid syntax

    Vermutlich liegt der Fehler in der Zeile darüber, aber egal, was ich probiere, es mag nicht funktionieren.

    Da ich mit meinem Latein am Ende bin, frage ich mal in die Runde.

    Wo liegt mein Fehler ? :helpnew:

  • [Gelöst] Python3 Werte mit Variable in mariadb schreiben? Schau mal ob du hier fündig wirst!

  • Code
    cursor.execute('INSERT INTO daten (temperatur, luftdruck, luftfeuchtigkeit, datumzeit) VALUES (temperatur, luftdruck, luftfeuchtigkeit, datumzeit)'

    Eine Zeile davor fehlt die runde Klammer am Ende.

    Code
    cursor.execute('INSERT INTO daten (temperatur, luftdruck, luftfeuchtigkeit, datumzeit) VALUES (temperatur, luftdruck, luftfeuchtigkeit, datumzeit)')

    Wo sind denn die Werte?!


    Bei sqlite3 kann man Platzhalter für Werte setzen. Das verhindert unter anderem eine mögliche SQL-injection (;DROP TABLE daten;).

    Code
    cursor.execute(
        'INSERT INTO daten (temperatur, luftdruck, luftfeuchtigkeit, datumzeit) VALUES (?, ?, ?, ?)',
        (20.0, 1.0, 0.48, "2022-08-02T12:23:00"),
    )

    Das zweite Argument ist eine Tupel mit den Werten, die eingefügt werden sollen.

    Die Werte werden der DB nicht einfach blind übergeben, sondern Steuerzeichen innerhalb der Werte werden sozusagen auskommentiert, damit SQL-Statements in Werten nicht als Code ausgeführt werden.

    Einmal editiert, zuletzt von RestlessMud46765 (8. Februar 2023 um 12:28)

  • Was sind denn ``float('%.2f' % data.temperature)`` für Aktionen? Theoretisch könnte man die Werte ja runden bevor man sie speichert, aber wenn dann nicht *so*, aber eigentlich stellt sich auch die Frage warum überhaupt? Einfach in die Datenbank schreiben und gut ist. Man könnte *dort* die Anzahl der Nachkommastellen bei der Spaltendefinition angeben wenn man mag, oder bei der Abfrage runden, oder bei der Darstellung nach der Abfrage.

    Die Spalte `datumzeit` sollte in der Datenbank einen passenden Typ haben und nicht als Zeichenkette gespeichert werden. Also beispielsweise den SQL-Typ TIMESTAMP. Und dann speichert man ein `datetime`-Objekt in der Datenbank und keine Zeichenkette. Dann bekommt man auch keine Probleme mit irgendwelchen Locale-Einstellungen in welchem Format ein Zeitstempel als Zeichenkette von der Datenbank erwartet/geliefert wird.

    `time` und `errorcode` aus `mysql.connector` werden importiert, aber nirgends verwendet.

    Das schliessen von Datenbankverbindung und Cursor sichert man am besten mit ``with`` und `contextlib.closing()` ab.

    Zwischenstand (ungetestet):

    Warum wird eigentlich `datumzeit` definiert wenn es doch ein `data.timestamp` gibt?

    Man muss sich bei lokalen Zeitstempeln auch immer klar machen, dass es so Sachen wie Sommer/Winterzeit-Umstellung gibt die man bei der Auswertung dann berücksichtigen muss, oder zweimal im Jahr ”komische” Zeit-/Werteverläufe hat.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Gelöst, da hat ein prepared=True bei cursor = db.cursor() gefehlt:

  • Datenbanken mögen es nicht, wenn Felder mit den falschen Datentypen befüllt werden sollen. Die einzige völlig schmerzfreie relationale Datenbank, die ich kenne, ist sqlite3.

    Du musst float übergeben, wenn die Felder float sind. Du übergibst str, was der falsche Datentyp ist. Manche Konnektoren machen eine automatische Konvertierung, aber darauf sollte man sich nicht verlassen.

    Man kann auch nicht alle Beispiele von sqlite3 auf MySQL übertragen.

    Ich denke mal, dass MySQL (mariadb) auch ein paar mehr Datentypen kennt, als sqlite3.

    Die Werte überträgst du übrigens immer noch im Query, das sich zum Hacken wunderbar ausnutzen lässt, wenn die Daten z.B. von einem Benutzer eingegeben werden und ungeprüft in den Query übernommen werden. Deswegen hat man die Möglichkeit, Query und Daten getrennt der execute-Methode zu übergeben.

    Gültiger SQL-Syntax in Daten wird unwirksam gemacht.

  • Du musst float übergeben, wenn die Felder float sind. Du übergibst str, was der falsche Datentyp ist. Manche Konnektoren machen eine automatische Konvertierung, aber darauf sollte man sich nicht verlassen.

    In der Datenbank sind die Spalten bis auf datumzeit auf float gestellt, damit sollte es doch auch als float in der db sein, oder ?

    Wenn ich im Script versuche, die Werte als float zu übergebgen, bekomme ich ja den Syntaxfehler.

    Die Werte überträgst du übrigens immer noch im Query, das sich zum Hacken wunderbar ausnutzen lässt, wenn die Daten z.B. von einem Benutzer eingegeben werden und ungeprüft in den Query übernommen werden. Deswegen hat man die Möglichkeit, Query und Daten getrennt der execute-Methode zu übergeben.

    Ich wüsste auch nicht wie es anders geht, mein Kontakt mit mysql beschränkt sich auf meine Schulzeit von anno dazumals.

    Aber der Benutzer lokalerbme280 hat ja seine eigene, gleichnamige Datenbank und darf dort nur INSERT durchführen, die Datenbank akzeptiert auch nur localhost. Könnte das trotzdem ein Problem sein ?

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!