Datensatz in mySQL-DB eintragen > Syntaxproblem

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
RoterMilaniX
User
Beiträge: 5
Registriert: Mittwoch 12. Oktober 2016, 21:58

Hallo zusammen,

kurz gesagt will ich über den Raspi gemessene Temperatur und Feuchte in eine mySQL-DB schreiben.

Die Struktur der mySQL-BD-Tabelle (werkstattklima) ist folgende:
Name (Typ)
zeitstempel (Timestamp)
temperatur (Decimal 5.2)
luftfeuchtigkeit (Decimal 5.2)

Im Pythonprogramm versuche ich die Daten so in die DB zu schreiben:

Code: Alles auswählen

sql = "INSERT INTO `Klimadaten`.`werkstattklima` (`zeitstempel`, `temperatur`, `luftfeuchtigkeit`) \
         VALUES ('%s', '%d', '%d')" % ('CURRENT_TIMESTAMP', Temp, Humidity)
Temp und Humidity werden so berechnet:

Code: Alles auswählen

Temp = -45 + (175 * temp / 65535.0)
Humidity = 100 * (data[3] * 256 + data[4]) / 65535.0
Es wird leider kein Eintrag in die DB geschrieben! Die Messung und die Ausgabe am Bildschirm funktionieren. In den Variablen Temp und Humidity stehen die Werte für Temperatur und Luftfeuchtigkeit.
Passt eventuell die Stringformatierung für CURRENT_TIMESTAMP nicht?

Wenn ich das testweise so mache funktioniert der Eintrag in die DB:

Code: Alles auswählen

sql = """INSERT INTO `Klimadaten`.`werkstattklima` (`zeitstempel`, `temperatur`, `luftfeuchtigkeit`) \
         VALUES (CURRENT_TIMESTAMP, '23.78', '48.56')"""
Wahrscheinlich nur ein Anfängerproblem ;-)

Danke vorab für eure Antworten.

Gruß RM
BlackJack

@RoterMilaniX: Was schon mal falsch ist ist das selber hineinformatieren von Werten in die SQL-Anfrage. Das überlässt man aus Sicherheits- und Performancegründen dem Datenbankmodul. Dazu muss man in der SQL-Anfrage die Platzhalter verwenden die das Datenbankmodul vorsieht und die Werte bei `execute()` als zweites Argument übergeben. CURRENT_TIMESTAMP ist dabei kein Wert! Genau an der Stelle unterscheiden sich Deine beiden Anfragen auch. Und die ' haben eigentlich auch bei den Zahlwerten nichts zu suchen. Ich weiss gar nicht ob der Standard das erlaubt DECIMAL-Werte als Zeichenketten in SQL anzugeben.

Das Du anscheinend keine Fehlermeldung bekommst ist komisch. Unterdrückst Du Ausnahmen durch falsche Ausnahmebehandlung?
RoterMilaniX
User
Beiträge: 5
Registriert: Mittwoch 12. Oktober 2016, 21:58

So geht's jetzt:

Code: Alles auswählen

...
sql = "INSERT INTO `Klimadaten`.`werkstattklima` (`zeitstempel`, `temperatur`, `luftfeuchtigkeit`) \
         VALUES (CURRENT_TIMESTAMP, '%5.2f', '%5.2f')" % (temp, humidity)

cursor.execute(sql)
...         
Habe ich das so richtig verstanden? "Dazu muss man in der SQL-Anfrage die Platzhalter verwenden die das Datenbankmodul vorsieht und die Werte bei `execute()` als zweites Argument übergeben."

Code: Alles auswählen

kl_data = ("INSERT INTO `Klimadaten`.`werkstattklima` (`zeitstempel`, `temperatur`, `luftfeuchtigkeit`) \
         VALUES (CURRENT_TIMESTAMP, '%5.2f', '%5.2f')")

kl_values = (temp, humidity)

cursor.execute(kl_data, kl_values)
Das Ergebnis ist doch das selbe woe bei oben stehendem Code, oder?

Gruß RM
BlackJack

@RoterMilaniX: Nein das ist nicht das selbe. Die Platzhalter für die Datenbank funktionieren nicht so wie die beim ``%``-Operator. Das sind wirklich nur Platzhalter für Werte ohne irgendwelche Formatierungen. Und auch ohne ' drum herum. Die wie gesagt auch bei der ersten Variante keinen Sinn machen weil es sich um Zahlen handelt und nicht um Zeichenketten.

Egal was Du denkst was geht oder nicht, die erste Variante geht gar nicht. Das ist wie beim Mann der aus dem Hochhausfenster springt und bei jeder Etage an der er vorbei fällt sagt „Hey, bis jetzt ist alles okay.“ ;-) Man formatiert niemals selbst irgendwelche Werte einfach so in Zeichenketten mit SQL-Anweisungen. Nicht in Python. Nicht bei MySQL. Und auch in keiner anderen Programmiersprache und keiner anderen SQL-Datenbank.
Antworten