Stundenzahl aus Datum herausfinden

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Vikardya
User
Beiträge: 12
Registriert: Mittwoch 3. Januar 2018, 15:48

Hallo :)

Ich habe ein Programm geschrieben, mit dem erfasst wird, wann ein RFID-Tag (bzw. Gerät mit Tag) ausgeliehen wird. In einer Datenbank wird dann gespeichert, unter welchem Benutzeraccount welcher RFID-Tag ausgeliehen wird. Dazu wird auch das aktuelle Datum & Zeit festgehalten (Mit datetime.now()).
Nun möchte ich herausfinden, wieviele RFID-Tags zwischen 0 und 4 Uhr ausgeliehen wurden. Meine Überlegung dazu war, dass ich erst einmal alle Einträge aus der Datenbank zähle und dann nur die herausfiltere, wo die Stundenzahl >= 0 und <4 ist. (Anschließend will ich noch wissen wie viele von 4-8h, von 8-12h, ...)
Das hat mit anderen Beispielen auch super funktioniert.
Mein Problem ist nun, dass ich die Stundenzahl nicht aus den einzelnen Daten bekomme, bzw. mir da komplett der Ansatz fehlt.
Meine Programmierung sieht momentan wie folgt aus:

data1 = ([], [])
tageszeit1 = 0
tageszeit2 = 4

for x in range(1):
vals1 = db_session.query(func.count(Ausleihen.Entliehen_am)) \
.filter(Ausleihen.Entliehen_am >= tageszeit1) \
.filter(Ausleihen.Entliehen_am < tageszeit2)
data1[x].append(int(vals1[0][0]))

Jetzt muss ich an den blau markierten Stellen ja noch sagen, dass ich da jeweils nur die Stunde haben will und nicht das ganze Datum, aber wie?
Bei datetime.now() geht das ja einfach, indem man ein ".hour" dahintersetzt, da wird mir hier aber (logischerweise) nur angezeigt, dass das nicht funktioniert.
Vielen Dank schon einmal im Voraus!
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bitte benutz code-tags, um deinen Code zu formatieren. Und es sieht so aus, als ob du ein ORM tool benutzt, welches das ist zu erwaehnen kann auch nicht schaden.

Was dein eigentliches Problem angeht: ich nehme mal an, dass du da mit einer Funktion deiner DB arbeiten musst (so wie du ja auch schon func.count benutzt), die in dem Fall aber das aequivalent zu .hour auf datetime ist. In postgres findet man die zB hier:

https://www.postgresql.org/docs/9.1/sta ... etime.html

Wie sich das dann genau durch dein ORM darstellen laesst - musst du gucken.
Vikardya
User
Beiträge: 12
Registriert: Mittwoch 3. Januar 2018, 15:48

Entschuldige, hatte ich total vergessen. Ich benutze SQLalchemy.
Und bin anscheinend trotzdem zu doof, den richtigen Befehl zu finden.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na dazu muss man noch deine DB kennen. Weiss auch keiner ;) Und ich kann dir nur raten, die SQLAlchemy Mailingliste zu abonnieren. Michael macht einen unglaublichen Job als Maintainer (oder hat zumindest als ich da noch aktiv war)
Vikardya
User
Beiträge: 12
Registriert: Mittwoch 3. Januar 2018, 15:48

Meine DB ist MySQL...
WIe man merkt, bin ich auf dem Gebiet wirklich eine Niete :roll:
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Vikardya: eine Googlesuche liefert gleich als erstes Ergebnis eine Stackoverflow-Frage: Group by hour in sqlalchemy. Dann würde ich alle Stunden gemeinsam abfragen und die viererpäckchen in Python bilden, oder gleich noch den Rest als SQL programmieren.

Code: Alles auswählen

count_per_hour = db_session.query(func.extract('hour', Ausleihen.Entliehen_am).label('hour'), func.count()).group_by('hour')
Vikardya
User
Beiträge: 12
Registriert: Mittwoch 3. Januar 2018, 15:48

@Sirius3: Vielen Dank, dieser "extract"-Befehl hat mir nur gefehlt :roll:
Jetzt funktioniert endlich alles :)
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Vikardya: Dir hat auch noch gefehlt, dass man mit group_by alles auf einmal abfragen kann. Man läßt am besten so viel wie sinnvoll durch die Datenbank auswerten.
Vikardya
User
Beiträge: 12
Registriert: Mittwoch 3. Januar 2018, 15:48

Vielen Dank nochmal!
Ich wollte das gleiche jetzt nochmal statt mit Stunden mit Wochentagen machen, dafür habe ich dann statt 'hour' 'isodow' benutzt. Nur da sagt mir mein Programm, dass da ein ProgrammingError vorliegt... mit dem Befehl 'dow' habe ich es ebenfalls ausprobiert.
Liegt es daran, dass ich einen falschen Befehl benutze? Oder ist irgendeins meiner Programme veraltet? :roll:
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bitte *konkrete* Fehlermeldungen, und wenn moeglich Versionen der eingesetzten Pakete und Anwendungen.
Vikardya
User
Beiträge: 12
Registriert: Mittwoch 3. Januar 2018, 15:48

Die konkrete Fehlermeldung:

ProgrammingError: (_mysql_exceptions.ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'isodow FROM ausleihen.`Entliehen_am`) = 1 \n LIMIT 1' at line 3") [SQL: u'SELECT count(ausleihen.`Nutzer`) AS count_1 \nFROM ausleihen \nWHERE EXTRACT(isodow FROM ausleihen.`Entliehen_am`) = %s \n LIMIT %s'] [parameters: (1, 1)]
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Guckst du Dokumentation zu EXTRACT bzw. den Feldern, die es erlaubt:

https://dev.mysql.com/doc/refman/5.5/en ... n_date-add

day ist also dein Freund. Oder statt EXTRACT mit einem Feld gleich DAYOFWEEK.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich muss mich korrigieren: DAY hilft dir natuerlich nicht. Also DAYOFWEEK ist es, aber OHNE EXTRACT!
Vikardya
User
Beiträge: 12
Registriert: Mittwoch 3. Januar 2018, 15:48

Danke! Hat (mal wieder) super funktioniert :)
Antworten