Guten Tag,
ich habe folgendes vor. Es geht um eine Datenbank für einen Sportverein. Die Datenbank ist fertig und läuft auf einem MYSQL Server. In der Datenbank sollen die Schützen erfasst werden, sobald diese einen Stand betretten und sich an einem Gerät anmelden. hier würde ich gern mit RFID und einem Raspberry arbeiten. Der User soll dann nach Anmeldung die Möglichkeit bekommen, sich seinen Platz auszuwählen. Das soll dann in die Datenbank geschrieben werden.
Ist der Schütze fertig soll er sich wieder mit RFID und der Funktion abmelden, von dem Stand abmelden.
Aktuell hat der Verein 5 Stände auf denen dann solche Geräte zum Einsatz kommen sollen. Das Gerät muss dann seinen Stand fest kennen, bzw über ein Merkmal des Gerätes diesen Ort mitteilen. Also wenn der Schütze auf dem 25 Meter Stand ist, soll das Endgerät das wissen und es soll nicht nochmal aus wählbar sein.
Per PHP und HTML habe ich bereits das Szenario soweit programmiert. Aber wie sollte ich am besten Starten, dass in Python umzusetzen? Ist das realisierbar so wie ich es mir vorstelle?
Bastel grade bissl rum mit pyQt.... Aber das ist schon alles erstmal sehr abstrakt.
Liebe Grüße und Danke für die IDeen.
Projekterstellung mit GUI
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@matze1708: Abstrakt ist ein gutes Stichwort. Was ist denn jetzt die konkrete Frage?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@matze1708: Die Beschreibung ist ja recht unkonkret. Etwas in der Richtung lässt sich sicher umsetzen, und anfangen kann man am Anfang. Also mit einer detaillierteren Anforderungsanalyse.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Ich versuche es mal .... weiss aber nicht ob es genug detaliert ist.
Also: Es handelt sich um ein Schiessbuch welches Digital werden soll. Dazu dachte ich, dass ich Raspberrys nehme mit Touch Display und einem RFID Reader.
Auf jedem der 5 Stände soll so ein Raspberry hängen. Die Schützen haben hierzu RFID Karten oder Anhänger.....
Ist der Schütze nun auf dem Stand muss er sich an de Gerät mit seiner Karte anmelden und auf einer Auswahl seinen Platz eintragen.
Damit soll dann ein Tabellen eintrag erzeugt werden.
Ist der Schütze fertig, geht er wieder an das Gerät und es wird in der Tabelle ein Eintrag erzeugt für das abmelden.
DB seitig habe ich das
tbl_Benutzer
tbl_Karten
tbl_Kaliber
tbl_Stand
tbl_Schiessbuch
Ein Benutzer kann X Karten haben. In der Tabelle tbl_karten, kann man KArten aktivieren und deaktiveren.
Benutzer können gesperrt werden etc.
In tbl_Kaliber, stehen die Kaliber die Geschossen werden können
in tbl_Stände, sind all unsere Stände hinterelgt
tbl_Schiessbuch ist eine Zusammenfassung über 1 zu n Beziehungen zu den vor genannten Tabellen.
Aber das Thema mit den Abfragen, Select, Insert etc bekomme ich hin.
Mir fehlt es nur am Python. und vorallem an der Grafischen Oberfläche.
Da kämpfe ich seit Montag mir PyQt etc.
Also: Es handelt sich um ein Schiessbuch welches Digital werden soll. Dazu dachte ich, dass ich Raspberrys nehme mit Touch Display und einem RFID Reader.
Auf jedem der 5 Stände soll so ein Raspberry hängen. Die Schützen haben hierzu RFID Karten oder Anhänger.....
Ist der Schütze nun auf dem Stand muss er sich an de Gerät mit seiner Karte anmelden und auf einer Auswahl seinen Platz eintragen.
Damit soll dann ein Tabellen eintrag erzeugt werden.
Ist der Schütze fertig, geht er wieder an das Gerät und es wird in der Tabelle ein Eintrag erzeugt für das abmelden.
DB seitig habe ich das
tbl_Benutzer
tbl_Karten
tbl_Kaliber
tbl_Stand
tbl_Schiessbuch
Ein Benutzer kann X Karten haben. In der Tabelle tbl_karten, kann man KArten aktivieren und deaktiveren.
Benutzer können gesperrt werden etc.
In tbl_Kaliber, stehen die Kaliber die Geschossen werden können
in tbl_Stände, sind all unsere Stände hinterelgt
tbl_Schiessbuch ist eine Zusammenfassung über 1 zu n Beziehungen zu den vor genannten Tabellen.
Aber das Thema mit den Abfragen, Select, Insert etc bekomme ich hin.
Mir fehlt es nur am Python. und vorallem an der Grafischen Oberfläche.
Da kämpfe ich seit Montag mir PyQt etc.
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@matze1708: Naja, das ist halt immer noch kein konkretes Problem was man irgendwie beantworten könnte.
So ganz allgemeine Anmerkungen: Der `tbl_`-Präfix ist unnötig. Bei Tabellennamen würde ich Einzahl verwenden, genau wie bei Klassen oder im ER/UML-Diagramm für die Datenbankstruktur. Auf jeden Fall aber konsistent, und nicht mal Einzahl (z.B. Stand) und mal Mehrzahl (z.B. Karten).
Für Datenbankzugriffe nehme ich fast immer SQLAlchemy als Zwischenschicht, meistens auch das ORM davon.
Die GUI wird ja erst wirklich interessant wenn die Programmlogik da ist. Das sollte man getrennt von der GUI machen.
So ganz allgemeine Anmerkungen: Der `tbl_`-Präfix ist unnötig. Bei Tabellennamen würde ich Einzahl verwenden, genau wie bei Klassen oder im ER/UML-Diagramm für die Datenbankstruktur. Auf jeden Fall aber konsistent, und nicht mal Einzahl (z.B. Stand) und mal Mehrzahl (z.B. Karten).
Für Datenbankzugriffe nehme ich fast immer SQLAlchemy als Zwischenschicht, meistens auch das ORM davon.
Die GUI wird ja erst wirklich interessant wenn die Programmlogik da ist. Das sollte man getrennt von der GUI machen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Genau das Hilft mir.Für Datenbankzugriffe nehme ich fast immer SQLAlchemy als Zwischenschicht, meistens auch das ORM davon.
Die GUI wird ja erst wirklich interessant wenn die Programmlogik da ist. Das sollte man getrennt von der GUI machen.
Bin nämlich am rum Doktoren mit Qt Designer/Creator
In der Hoffnung ich bekomme da was hin, hätte dann da parallel die Logik miteibgebaut.
Für SQL habe ich aktuell Mysqldb genutzt mit erfolg.
Und über pyqt bin ich auch an die DB gekommen.
QMysql
Dann hört es aber aktuell auch auf.
Weil ich gern ein festes Fenster hätte, das auf RFID eingabe wartet und dann zum nächsten Springt.
Schaue ich mir mal deine beiden Dinge an und blende mal die GUI aus.
Dachte es macht Sinn direkt mit GUI
Hallo,
ich habe nun mal etwas rudimentäres entworfen.
Lässt sich das jetzt hier schon etwas besser Strukturieren und abkürzen?
Kann ich den Connection Part auch in eine Funktion schreiben, um die nicht immer wieder aufzurufen?
Geil wäre halt ne richtige Grafik Oberfläche.
Einiges an Logik werde ich noch einbauen. Damit der Ablauf einfacher wird.
Achso, bei Umlauten ß,ö etc werden mir ? ausgeben. Habe da mit utf8 etc mal rumgespielt, kam aber immer das gleiche raus.
ich habe nun mal etwas rudimentäres entworfen.
Lässt sich das jetzt hier schon etwas besser Strukturieren und abkürzen?
Kann ich den Connection Part auch in eine Funktion schreiben, um die nicht immer wieder aufzurufen?
Geil wäre halt ne richtige Grafik Oberfläche.
Einiges an Logik werde ich noch einbauen. Damit der Ablauf einfacher wird.
Achso, bei Umlauten ß,ö etc werden mir ? ausgeben. Habe da mit utf8 etc mal rumgespielt, kam aber immer das gleiche raus.
Code: Alles auswählen
#!/usr/bin/python3
# -*- coding: iso-8859-1 -*-
# -*- encoding: iso-8859-15 -*-
# SchuetzeAnlegen.py
import sys
import RPi.GPIO as GPIO
import MFRC522
import signal
import MySQLdb
import datetime
print("Schiessbuch")
print
print("Bitte erfasse deine Daten!")
print
def BenutzerAnzeigen():
print
try:
mydb = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
mycursor = mydb.cursor(MySQLdb.cursors.DictCursor)
with mydb:
mycursor.execute("Select tbl_Benutzer.ID, tbl_Benutzer.UName, tbl_Benutzer.UVorname FROM tbl_Benutzer INNER JOIN tbl_Karten ON tbl_Benutzer.ID = tbl_Karten.UserID")
rows = mycursor.fetchall()
for row in rows:
print row["ID"], row["UName"], row["UVorname"]
except MySQLdb.Error as error :
mydb.rollback()
print("Failed to insert into MySQL table {}".format(error))
finally:
#closing database connection.
if(mydb.ping()):
mycursor.close()
mydb.close()
print("MySQL connection is closed")
BenutzerAnzeigen()
try:
print
var_User = int(input("Bitte deine User ID eingeben: "))
except:
print("Fehler: Keine Zahl eingegeben.")
sys.exit()
def StandAnzeigen():
print
try:
mydb = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
mycursor = mydb.cursor(MySQLdb.cursors.DictCursor)
with mydb:
mycursor.execute("Select ID, StandLang From tbl_Stand")
rows = mycursor.fetchall()
for row in rows:
print row["ID"], row["StandLang"]
except MySQLdb.Error as error :
mydb.rollback()
print("Failed to insert into MySQL table {}".format(error))
finally:
#closing database connection.
if(mydb.ping()):
mycursor.close()
mydb.close()
print("MySQL connection is closed")
StandAnzeigen()
try:
print
var_StandID = int(input("Bitte Stand eingeben: "))
except:
print("Fehler: Keine Zahl eingegeben.")
sys.exit()
def KaliberAnzeigen():
print
try:
mydb = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
mycursor = mydb.cursor(MySQLdb.cursors.DictCursor)
with mydb:
mycursor.execute("Select ID, KaliberLang From tbl_Kaliber")
rows = mycursor.fetchall()
for row in rows:
print row["ID"], row["KaliberLang"]
except MySQLdb.Error as error :
mydb.rollback()
print("Failed to insert into MySQL table {}".format(error))
finally:
#closing database connection.
if(mydb.ping()):
mycursor.close()
mydb.close()
print("MySQL connection is closed")
KaliberAnzeigen()
try:
print
var_KaliberID = int(input("Bitte Kaliber eingeben: "))
except:
print("Fehler: Keine Zahl eingegeben.")
sys.exit()
#Anfrage Platz
print
try:
var_Platz = int(input("Auf welchem Stand schiesst du?: "))
except:
print("Fehler: Keine Zahl eingegeben.")
sys.exit()
var_Standaufsicht = 0
var_BeginnZeit = datetime.datetime.now()
def Schuetzeanlegen(User, StandID, Platz, KaliberID, Beginn, Standaufsicht):
print
try:
mydb = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
mycursor = mydb.cursor()
sql1 = """INSERT INTO `tbl_Schiesstand` (`UserID`, `StandID`, `Platz`, `KaliberID`, `Beginn`, `Standaufsicht`) VALUES (%s, %s, %s, %s, %s, %s)"""
sqlInsertData = (User, StandID, Platz, KaliberID, Beginn, Standaufsicht)
mycursor.execute(sql1, sqlInsertData)
mydb.commit()
print
print ("Du wurdest erfolgreich registriert")
except MySQLdb.Error as error :
mydb.rollback()
print("Failed to insert into MySQL table {}".format(error))
finally:
#closing database connection.
if(mydb.ping()):
mycursor.close()
mydb.close()
print("MySQL connection is closed")
Schuetzeanlegen(var_User, var_StandID, var_Platz, var_KaliberID, var_BeginnZeit, var_Standaufsicht)
Bei Python3 haben einfache `print`-Referenzierungen keine Wirkung, Du mußt `print` aufrufen.
Halte Dich an die Namenskonvention: Funktionen, wie Variablennamen schreibt man klein_mit_unterstrich.
Die `my`-Präfixe bei Deinen ganzen Variablen sind überflüssig (oder gibt es auch yourdb?).
Vermeide auch Abkürzungen bei Tabellen. Was soll bei UName und UVorname das U?
Wenn Du mit `with` arbeitest, sollte im Fehlerfall das `rollback` automatisch ablaufen, das muß man nicht explizit aufrufen. Die Fehlerausgabe ist auch Falsch, weil Du im try-Block gar kein `INSERT` ausführst. Wenn Du eine Exception nicht sinnvoll abarbeiten kannst, dann als es ganz sein.
`if` ist keine Funktion, die Klammern also überflüssig.
Im Fehlerfall ist im zweifel `mydb` nicht definiert, ein `mydb.ping` führt also zu einen NameError.
Niemals nackte `except` benutzen, sondern nur konkrete Fehlermeldungen abfangen. Bei "User ID eingeben" kann die Umwandlung in int fehlschlagen, das gibt einen ValueError. Wenn keine Zahl eingegeben wurde, besser nochmal nachfragen. `sys.exit` hat in einem sauberen Programm nichts verloren. Von daher sollte aller ausführbarer Code nicht auf oberster Ebene stehen, sondern in eine Funktion wandern, die normalerweise `main` genannt wird. Die kann man dann einfach durch `return` verlassen. Damit ergibt sich auch automatisch die nächste Forderunge: niemals ausführbaren Code und Funktionsdefinitionen mischen.
Es ist schlecht, dass jede Funktion wieder die Datenbank öffnet, so hast Du an vielen Stellen gleichen Code und mußt sogar bei Änderungen des Passworts das an vielen Stellen wiederholen. Besser eine Funktion schreiben, die die Datenbank öffnet (Username/Passwort etc. als Konstanten am Anfang der Datei (oder in einer Konfigurationsdatei)) speichern). Die Datenbankinstanz dann an die Funktionen als Parameter übergeben. Die bleibt während des gesamten Programmablaufs geöffnet.
Stand-ID-Abfrage ist wieder fast der selbe Code wie User-ID, das ist also besser eine Funktion, die mit unterschiedlichen Parametern aufgerufen wird.
In `Schuetzeanlegen` benutzt Du dann kein `with mydb:`. Warum?
Das var-Präfix ist wie das my-Präfix Unsinn.
Halte Dich an die Namenskonvention: Funktionen, wie Variablennamen schreibt man klein_mit_unterstrich.
Die `my`-Präfixe bei Deinen ganzen Variablen sind überflüssig (oder gibt es auch yourdb?).
Vermeide auch Abkürzungen bei Tabellen. Was soll bei UName und UVorname das U?
Wenn Du mit `with` arbeitest, sollte im Fehlerfall das `rollback` automatisch ablaufen, das muß man nicht explizit aufrufen. Die Fehlerausgabe ist auch Falsch, weil Du im try-Block gar kein `INSERT` ausführst. Wenn Du eine Exception nicht sinnvoll abarbeiten kannst, dann als es ganz sein.
`if` ist keine Funktion, die Klammern also überflüssig.
Im Fehlerfall ist im zweifel `mydb` nicht definiert, ein `mydb.ping` führt also zu einen NameError.
Niemals nackte `except` benutzen, sondern nur konkrete Fehlermeldungen abfangen. Bei "User ID eingeben" kann die Umwandlung in int fehlschlagen, das gibt einen ValueError. Wenn keine Zahl eingegeben wurde, besser nochmal nachfragen. `sys.exit` hat in einem sauberen Programm nichts verloren. Von daher sollte aller ausführbarer Code nicht auf oberster Ebene stehen, sondern in eine Funktion wandern, die normalerweise `main` genannt wird. Die kann man dann einfach durch `return` verlassen. Damit ergibt sich auch automatisch die nächste Forderunge: niemals ausführbaren Code und Funktionsdefinitionen mischen.
Es ist schlecht, dass jede Funktion wieder die Datenbank öffnet, so hast Du an vielen Stellen gleichen Code und mußt sogar bei Änderungen des Passworts das an vielen Stellen wiederholen. Besser eine Funktion schreiben, die die Datenbank öffnet (Username/Passwort etc. als Konstanten am Anfang der Datei (oder in einer Konfigurationsdatei)) speichern). Die Datenbankinstanz dann an die Funktionen als Parameter übergeben. Die bleibt während des gesamten Programmablaufs geöffnet.
Stand-ID-Abfrage ist wieder fast der selbe Code wie User-ID, das ist also besser eine Funktion, die mit unterschiedlichen Parametern aufgerufen wird.
In `Schuetzeanlegen` benutzt Du dann kein `with mydb:`. Warum?
Das var-Präfix ist wie das my-Präfix Unsinn.
Guten Morgen,
ich muss deine Hilfe erstmal langsam verstehen.
ich habe mal aus mydb db gemacht und mycursor Cursor
dann habe ich alles aufrufbare in eine def main(): gepackt
Das try and expec habe ich bei den Select Anweisungen gelöscht.
Was ich gerade überlege ist, wie ich gescheit den connect der db in eine Funktion verwurste
UName und UVorname sind User Name und User Vorname
Das habe ich so gemacht, weil oft in der SQL Welt Name als Referenz zum einem Objekt steht.
So sieht der COde gerade aus:
ich muss deine Hilfe erstmal langsam verstehen.
ich habe mal aus mydb db gemacht und mycursor Cursor
dann habe ich alles aufrufbare in eine def main(): gepackt
Das try and expec habe ich bei den Select Anweisungen gelöscht.
Was ich gerade überlege ist, wie ich gescheit den connect der db in eine Funktion verwurste
UName und UVorname sind User Name und User Vorname
Das habe ich so gemacht, weil oft in der SQL Welt Name als Referenz zum einem Objekt steht.
So sieht der COde gerade aus:
Code: Alles auswählen
#!/usr/bin/python3
# -*- coding: iso-8859-1 -*-
# -*- encoding: iso-8859-15 -*-
# SchuetzeAnlegen.py
import sys
import RPi.GPIO as GPIO
import MFRC522
import signal
import MySQLdb
import datetime
def main():
var_Standaufsicht = 0
var_BeginnZeit = datetime.datetime.now()
print("Schiessbuch")
print
print("Bitte erfasse deine Daten!")
print
BenutzerAnzeigen()
try:
print
var_User = int(input("Bitte deine User ID eingeben: "))
except:
print("Fehler: Keine Zahl eingegeben.")
StandAnzeigen()
try:
print
var_StandID = int(input("Bitte Stand eingeben: "))
except:
print("Fehler: Keine Zahl eingegeben.")
KaliberAnzeigen()
try:
print
var_KaliberID = int(input("Bitte Kaliber eingeben: "))
except:
print("Fehler: Keine Zahl eingegeben.")
#Anfrage Platz
print
try:
var_Platz = int(input("Auf welchem Stand schiesst du?: "))
except:
print("Fehler: Keine Zahl eingegeben.")
Schuetzeanlegen(var_User, var_StandID, var_Platz, var_KaliberID, var_BeginnZeit, var_Standaufsicht)
def dbconnect():
db = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
cursor = db.cursor(MySQLdb.cursors.DictCursor)
return db, cursor
def BenutzerAnzeigen():
print
db = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
cursor = db.cursor(MySQLdb.cursors.DictCursor)
with db:
cursor.execute("Select tbl_Benutzer.ID, tbl_Benutzer.UName, tbl_Benutzer.UVorname FROM tbl_Benutzer INNER JOIN tbl_Karten ON tbl_Benutzer.ID = tbl_Karten.UserID")
rows = cursor.fetchall()
for row in rows:
print row["ID"], row["UName"], row["UVorname"]
def StandAnzeigen():
print
db = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
cursor = db.cursor(MySQLdb.cursors.DictCursor)
with db:
cursor.execute("Select ID, StandLang From tbl_Stand")
rows = cursor.fetchall()
for row in rows:
print row["ID"], row["StandLang"]
def KaliberAnzeigen():
print
db = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
cursor = db.cursor(MySQLdb.cursors.DictCursor)
with db:
cursor.execute("Select ID, KaliberLang From tbl_Kaliber")
rows = cursor.fetchall()
for row in rows:
print row["ID"], row["KaliberLang"]
def Schuetzeanlegen(User, StandID, Platz, KaliberID, Beginn, Standaufsicht):
print
try:
db = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
cursor = db.cursor()
sql1 = """INSERT INTO `tbl_Schiesstand` (`UserID`, `StandID`, `Platz`, `KaliberID`, `Beginn`, `Standaufsicht`) VALUES (%s, %s, %s, %s, %s, %s)"""
sqlInsertData = (User, StandID, Platz, KaliberID, Beginn, Standaufsicht)
cursor.execute(sql1, sqlInsertData)
db.commit()
print
print ("Du wurdest erfolgreich registriert")
except MySQLdb.Error as error :
db.rollback()
print("Failed to insert into MySQL table {}".format(error))
finally:
#closing database connection.
if(db.ping()):
cursor.close()
db.close()
print("MySQL connection is closed")
main()
Der Code wird übersichtlicher *freu
Habe ein def connect(): eingebaut mit return
Dazu habe ich ein WHERE Statement eingebaut, um nach der Standselektion nur noch die korrekten Kaliber zubekommen.
Dazu habe ich in der Datenbank eine weitere Abhängigkeit zu den Tabellen Kaliber und Stand eingebaut.
Habe ein def connect(): eingebaut mit return
Dazu habe ich ein WHERE Statement eingebaut, um nach der Standselektion nur noch die korrekten Kaliber zubekommen.
Dazu habe ich in der Datenbank eine weitere Abhängigkeit zu den Tabellen Kaliber und Stand eingebaut.
Code: Alles auswählen
#!/usr/bin/python3
# -*- coding: iso-8859-1 -*-
# -*- encoding: iso-8859-15 -*-
# SchuetzeAnlegen.py
import sys
import RPi.GPIO as GPIO
import MFRC522
import signal
import MySQLdb
import datetime
def main():
var_Standaufsicht = 0
var_BeginnZeit = datetime.datetime.now()
print("Schiessbuch")
print
print("Bitte erfasse deine Daten!")
print
BenutzerAnzeigen()
try:
print
var_User = int(input("Bitte deine User ID eingeben: "))
except:
print("Fehler: Keine Zahl eingegeben.")
StandAnzeigen()
try:
print
var_StandID = int(input("Bitte Stand eingeben: "))
except:
print("Fehler: Keine Zahl eingegeben.")
KaliberAnzeigen(var_StandID)
try:
print
var_KaliberID = int(input("Bitte Kaliber eingeben: "))
except:
print("Fehler: Keine Zahl eingegeben.")
#Anfrage Platz
print
try:
var_Platz = int(input("Auf welchem Stand schiesst du?: "))
except:
print("Fehler: Keine Zahl eingegeben.")
Schuetzeanlegen(var_User, var_StandID, var_Platz, var_KaliberID, var_BeginnZeit, var_Standaufsicht)
def connect():
db = MySQLdb.connect(host="10.100.124.14", user="XXX", passwd="XXX", db="Schiessbuch", port=3307)
cursor = db.cursor(MySQLdb.cursors.DictCursor)
return cursor, db
def BenutzerAnzeigen():
print
cursor, db = connect()
with db:
cursor.execute("Select tbl_Benutzer.ID, tbl_Benutzer.UName, tbl_Benutzer.UVorname FROM tbl_Benutzer INNER JOIN tbl_Karten ON tbl_Benutzer.ID = tbl_Karten.UserID")
rows = cursor.fetchall()
for row in rows:
print row["ID"], row["UName"], row["UVorname"]
def StandAnzeigen():
print
db = MySQLdb.connect(host="10.100.124.14", user="Web_Schiessbuch", passwd="Pw$Schiessbuch", db="Schiessbuch", port=3307)
cursor = db.cursor(MySQLdb.cursors.DictCursor)
with db:
cursor.execute("Select ID, StandLang From tbl_Stand")
rows = cursor.fetchall()
for row in rows:
print row["ID"], row["StandLang"]
def KaliberAnzeigen(standID):
print
cursor, db = connect()
with db:
cursor.execute("Select tbl_Kaliber.ID, tbl_Kaliber.KaliberLang, tbl_Stand.Standlang From tbl_Stand INNER JOIN tbl_Kaliber ON tbl_Stand.ID = tbl_Kaliber.StandID Where tbl_Stand.ID = %s", (standID,))
rows = cursor.fetchall()
for row in rows:
print row["ID"], row["KaliberLang"]
def Schuetzeanlegen(User, StandID, Platz, KaliberID, Beginn, Standaufsicht):
print
try:
cursor, db = connect()
sql1 = """INSERT INTO `tbl_Schiesstand` (`UserID`, `StandID`, `Platz`, `KaliberID`, `Beginn`, `Standaufsicht`) VALUES (%s, %s, %s, %s, %s, %s)"""
sqlInsertData = (User, StandID, Platz, KaliberID, Beginn, Standaufsicht)
cursor.execute(sql1, sqlInsertData)
db.commit()
print
print ("Du wurdest erfolgreich registriert")
except MySQLdb.Error as error :
db.rollback()
print("Failed to insert into MySQL table {}".format(error))
finally:
#closing database connection.
if(db.ping()):
cursor.close()
db.close()
print("MySQL connection is closed")
connect()
main()
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@matze1708: Die Begründung für das U verstehe ich nicht. Das es sich um einen Benutzernamen handelt, wird ja schon dadurch klar, dass der Name in der Benutzer-Tabelle ist. Das ist genau wie bei anderen Programmiersprachen mit Verbunddatentypen wo man den Namen des Datentyps ja auch nicht vor alle Felder/Attribute stellt. Auch bei SQL haben kryptische Abkürzungen das Problem, dass sie, nun ja, kryptisch sind, also müsste die Spalte ja eigentlich `benutzer_vorname` heissen. Und kann dann über `benutzer.benutzer_vorname` angesprochen werden. Was aber so gar keinen Vorteil gegebenüber `benutzer.vorname` hat. 'U' ist übrigens auch deswegen blöd weil die Tabelle bei Dir ja Deutsch benannt ist und eine englischer mit einem Buchstaben abgekürzter Präfix alles andere als naheliegend ist.
Und wenn ein Name in SQL ein Fremdschlüssel ist, also das was bei OOP eine Referenz zu einem anderen Objekt ist, dann hängt man da üblicherweise einen `_id`-Suffix an den Namen um Referenzen von direkten Werten unterscheiden zu können. Wenn man ein ORM verwendet, kann man den Namen ohne diesen Suffix dann tatsächlich für eine Referenz zu dem entsprechenden Objekt verwenden.
Bei SQL verwende ich nur Kleinbuchstaben für Namen und ansonsten die gleichen Namenskonventionen wie für Python, das macht die Abbildung auf Objekte mit einem ORM einfacher. Nur Kleinbuchstaben weil SQL die Gross-/Kleinschreibung bei Namen ja egal ist. In Fehlermeldungen werden einem Namen dann im Zweifelsfall komplett klein oder komplett gross geschrieben angezeigt, und da sind Unterstriche zwischen den einzelnen Worten aus denen ein Name zusammengesetzt ist, leichter zu lesen, als wenn das alles ohne visuelle Trennung hintereinander geklatscht wird.
Wie ist der Quelltext denn nun tatsächlich kodiert? Und was spricht gegen UTF-8? Nicht nur dass man die Kodierung für den Quelltext dann nicht angeben muss, man kann auch alle Unicode-Zeichen im Quelltext verwenden.
Der Quelltext ist kein Python 3, das heisst wenn Du den ausgeführt hast, dann mit Python 2. Die erste Zeile wäre dann also falsch, beziehungsweise sollte Du *wirklich* Python 3 verwenden. Python 2 ist am Ende.
Vier von den sechs Importen werden überhaupt nicht verwendet.
Der `connect()`-Aufruf auf Modulebene macht keinen Sinn, weil da ja auch gar nichts mit den Rückgabewerten gemacht wird.
Das ist auch so noch nicht sinnvoll gelöst, weil die DB-Verbindung etwas ist was langlebiger sein sollte. Die erstellt man in der Regel einmal und reicht sie dann als Argument herum.
In einer Funktion machst Du dann doch noch mal eine Verbindung nicht über die `connect()`-Funktion auf.
Geh mal bitte durch den Quelltext um passe alle Namen an die Python-Konventionen an. Siehe auch den Style Guide for Python Code.
Das ``with db:`` funktioniert ist ein Implementierungsdetail von `MySQLdb`. Das wird nicht von der DB API v2 garantiert und muss bei anderen Modulen für MySQL oder auch anderen DBMS nicht funktionieren. Da fehlt also ein `contextlib.closing()` damit man ``with`` verwenden kann.
`Cursor`-Objekte muss man auch schliessen. Nicht jedes DB-Modul/DBMS fordert das tatsächlich, aber die DB API v2 sagt, dass das gefordert werden kann.
Für den Zugriff auch ”Datensatz-Wörterbücher” finde ich das externe `addict`-Modul mit seinem `Dict`-Datentyp sehr praktisch. Wobei da dann auch die Bennung der Datenbankspalten nach Python-Namenskonventionen Sinn macht.
Das die Datenbankabfragen mit Anzeigen für den Benutzer vermischt sind ist nicht gut. Die Programmlogik sollte von der Benutzerinteraktion getrennt sein. Man möchte die Programmlogik ja nicht noch einmal programmieren, nur weil man die Daten dann in einer GUI ausgibt, statt per `print()` in einer Textkonsole.
Ich muss dann auch einfach noch mal SQLAlchemy erwähnen. Selbst wenn man das ORM nicht verwendet, macht es einem die Arbeit mit SQL-Datenbanken einfacher. Ich sehe aber auch keinen Grund das ORM hier nicht zu verwenden. Objekte denen man auch Methoden verpassen kann und das man die SQL-Abfragen nicht mehr selbst schreiben muss machen das ganze leichter.
Und wenn ein Name in SQL ein Fremdschlüssel ist, also das was bei OOP eine Referenz zu einem anderen Objekt ist, dann hängt man da üblicherweise einen `_id`-Suffix an den Namen um Referenzen von direkten Werten unterscheiden zu können. Wenn man ein ORM verwendet, kann man den Namen ohne diesen Suffix dann tatsächlich für eine Referenz zu dem entsprechenden Objekt verwenden.
Bei SQL verwende ich nur Kleinbuchstaben für Namen und ansonsten die gleichen Namenskonventionen wie für Python, das macht die Abbildung auf Objekte mit einem ORM einfacher. Nur Kleinbuchstaben weil SQL die Gross-/Kleinschreibung bei Namen ja egal ist. In Fehlermeldungen werden einem Namen dann im Zweifelsfall komplett klein oder komplett gross geschrieben angezeigt, und da sind Unterstriche zwischen den einzelnen Worten aus denen ein Name zusammengesetzt ist, leichter zu lesen, als wenn das alles ohne visuelle Trennung hintereinander geklatscht wird.
Wie ist der Quelltext denn nun tatsächlich kodiert? Und was spricht gegen UTF-8? Nicht nur dass man die Kodierung für den Quelltext dann nicht angeben muss, man kann auch alle Unicode-Zeichen im Quelltext verwenden.
Der Quelltext ist kein Python 3, das heisst wenn Du den ausgeführt hast, dann mit Python 2. Die erste Zeile wäre dann also falsch, beziehungsweise sollte Du *wirklich* Python 3 verwenden. Python 2 ist am Ende.
Vier von den sechs Importen werden überhaupt nicht verwendet.
Der `connect()`-Aufruf auf Modulebene macht keinen Sinn, weil da ja auch gar nichts mit den Rückgabewerten gemacht wird.
Das ist auch so noch nicht sinnvoll gelöst, weil die DB-Verbindung etwas ist was langlebiger sein sollte. Die erstellt man in der Regel einmal und reicht sie dann als Argument herum.
In einer Funktion machst Du dann doch noch mal eine Verbindung nicht über die `connect()`-Funktion auf.
Geh mal bitte durch den Quelltext um passe alle Namen an die Python-Konventionen an. Siehe auch den Style Guide for Python Code.
Das ``with db:`` funktioniert ist ein Implementierungsdetail von `MySQLdb`. Das wird nicht von der DB API v2 garantiert und muss bei anderen Modulen für MySQL oder auch anderen DBMS nicht funktionieren. Da fehlt also ein `contextlib.closing()` damit man ``with`` verwenden kann.
`Cursor`-Objekte muss man auch schliessen. Nicht jedes DB-Modul/DBMS fordert das tatsächlich, aber die DB API v2 sagt, dass das gefordert werden kann.
Für den Zugriff auch ”Datensatz-Wörterbücher” finde ich das externe `addict`-Modul mit seinem `Dict`-Datentyp sehr praktisch. Wobei da dann auch die Bennung der Datenbankspalten nach Python-Namenskonventionen Sinn macht.
Das die Datenbankabfragen mit Anzeigen für den Benutzer vermischt sind ist nicht gut. Die Programmlogik sollte von der Benutzerinteraktion getrennt sein. Man möchte die Programmlogik ja nicht noch einmal programmieren, nur weil man die Daten dann in einer GUI ausgibt, statt per `print()` in einer Textkonsole.
Ich muss dann auch einfach noch mal SQLAlchemy erwähnen. Selbst wenn man das ORM nicht verwendet, macht es einem die Arbeit mit SQL-Datenbanken einfacher. Ich sehe aber auch keinen Grund das ORM hier nicht zu verwenden. Objekte denen man auch Methoden verpassen kann und das man die SQL-Abfragen nicht mehr selbst schreiben muss machen das ganze leichter.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Hast Du jetzt das richtige Passwort hier gepostet? `Pw$Schiessbuch` solltest Du aber sowieso ändern, das ist zu einfach.
Wie schon geschrieben, solltest Du nicht jedes mal eine neue Verbindung zur Datenbank aufbauen, sondern einmal am Anfang. Ein Cursor dagegen ist etwas kurzlebiges und sollte dann erzeugt werden, wenn man konkret eine Abfrage macht, das geht am einfachsten mit `with`.
Die Namen halten sich immer noch nicht an die Konvention und auch bei Datenbanktabellen sollte man auf sprechende Namen setzen. Dazu gehört dass das überflüssige tbl_-Präfix wegkommt.
Codierung sollte unter Python3 eigentlich immer UTF8 (das ist der Default) sein.
Wie schon geschrieben, solltest Du nicht jedes mal eine neue Verbindung zur Datenbank aufbauen, sondern einmal am Anfang. Ein Cursor dagegen ist etwas kurzlebiges und sollte dann erzeugt werden, wenn man konkret eine Abfrage macht, das geht am einfachsten mit `with`.
Die Namen halten sich immer noch nicht an die Konvention und auch bei Datenbanktabellen sollte man auf sprechende Namen setzen. Dazu gehört dass das überflüssige tbl_-Präfix wegkommt.
Codierung sollte unter Python3 eigentlich immer UTF8 (das ist der Default) sein.
Code: Alles auswählen
#!/usr/bin/python3
import sys
import RPi.GPIO as gpio
import MFRC522
import MySQLdb
DB_HOST = "10.100.124.14"
DB_USER = "XXX"
DB_PASSWORD = "XXX"
def connect():
return MySQLdb.connect(host=DB_HOST, port=3307,
user=DB_USER , passwd=DB_PASSWORD, db="Schiessbuch",
cursorclass=MySQLdb.cursors.DictCursor)
def benutzer_anzeigen(db):
print()
with db as cursor:
cursor.execute("""Select tbl_Benutzer.ID, tbl_Benutzer.UName, tbl_Benutzer.UVorname
FROM tbl_Benutzer INNER JOIN tbl_Karten ON tbl_Benutzer.ID = tbl_Karten.UserID""")
for row in cursor:
print row["ID"], row["UName"], row["UVorname"]
def stand_anzeigen(db):
print()
with db as cursor:
cursor.execute("Select ID, StandLang From tbl_Stand")
for row in cursor:
print row["ID"], row["StandLang"]
def kaliber_anzeigen(stand_id):
print()
with db as cursor:
cursor.execute("""Select tbl_Kaliber.ID, tbl_Kaliber.KaliberLang, tbl_Stand.Standlang
From tbl_Stand INNER JOIN tbl_Kaliber ON tbl_Stand.ID = tbl_Kaliber.StandID
Where tbl_Stand.ID = %s""", (stand_id,))
for row in cursor:
print row["ID"], row["KaliberLang"]
def schuetze_anlegen(user_id, stand_id, platz, kaliber_id, standaufsicht):
print()
with db as cursor:
sql_query = """INSERT INTO `tbl_Schiesstand` (`UserID`, `StandID`, `Platz`, `KaliberID`, `Beginn`, `Standaufsicht`) VALUES (%s, %s, %s, %s, NOW(), %s)"""
data = (user_id, stand_id, platz, kaliber_id, standaufsicht)
cursor.execute(sql_query, data)
print()
print("Du wurdest erfolgreich registriert")
def input_int(prompt):
while True:
try:
print()
return int(input(prompt))
except ValueError:
print("Fehler: Keine Zahl eingegeben.")
def main():
print("Schiessbuch")
print()
print("Bitte erfasse deine Daten!")
print()
db = connect()
benutzer_anzeigen(db)
user_id = input_int("Bitte deine User ID eingeben: ")
stand_anzeigen(db)
stand_id = input_int("Bitte Stand eingeben: ")
kaliber_anzeigen(stand_id)
kaliber_id = input_int("Bitte Kaliber eingeben: ")
platz = input_int("Auf welchem Stand schiesst du?: ")
standaufsicht = 0
schuetze_anlegen(user_id, stand_id, platz, kaliber_id, standaufsicht)
if __name__ == '__main__':
main()
Hallo,
Danke für deine ausführliche Hilfe.
Ich muss mich da mal Schritt für Schritt durch arbeiten.
Habe gesehen das bei einem Fehler irgendwas mit Python 2.7 angezeigt worden ist.
Danke für deine ausführliche Hilfe.
Ich muss mich da mal Schritt für Schritt durch arbeiten.
Ich habe das ISo im Kopf entfernt und folgendes eingetragen:Wie ist der Quelltext denn nun tatsächlich kodiert? Und was spricht gegen UTF-8? Nicht nur dass man die Kodierung für den Quelltext dann nicht angeben muss, man kann auch alle Unicode-Zeichen im Quelltext verwenden.
Code: Alles auswählen
# -*- coding: utf-8 -*-
Wie bekomme ich das einheitlich auf Python 3?Der Quelltext ist kein Python 3, das heisst wenn Du den ausgeführt hast, dann mit Python 2. Die erste Zeile wäre dann also falsch, beziehungsweise sollte Du *wirklich* Python 3 verwenden. Python 2 ist am Ende.
Habe gesehen das bei einem Fehler irgendwas mit Python 2.7 angezeigt worden ist.
Hierbei wäre ich um Beispiel glücklich. Habe mich da in diversen Beiträgen belesen, und kann leider nur die Funktion def connect(): finden die man dann vor der main ausführt.Der `connect()`-Aufruf auf Modulebene macht keinen Sinn, weil da ja auch gar nichts mit den Rückgabewerten gemacht wird.
Das ist auch so noch nicht sinnvoll gelöst, weil die DB-Verbindung etwas ist was langlebiger sein sollte. Die erstellt man in der Regel einmal und reicht sie dann als Argument herum.
In einer Funktion machst Du dann doch noch mal eine Verbindung nicht über die `connect()`-Funktion auf.
Das dachte ich getan zu haben in der letzten Funktion unter finaly`Cursor`-Objekte muss man auch schliessen. Nicht jedes DB-Modul/DBMS fordert das tatsächlich, aber die DB API v2 sagt, dass das gefordert werden kann.
Danke für dein Beispiel.
das sieht ja ganz anders aus
Muss ich mir nach dem Mittag mal in Ruhe durchsehen und verstehen
Ich werde die Namen in der DB anpassen.
Ich habe mal mit Access und MSSQL angefangen. Da hat es sich einfacher gezeigt, Tabellen mit tbl_ und Abfragen qry_ oder Stored Procedur mit SP_ anzufangen. Daher habe ich das hier auch so getan.
das sieht ja ganz anders aus
Muss ich mir nach dem Mittag mal in Ruhe durchsehen und verstehen
Ich werde die Namen in der DB anpassen.
Ich habe mal mit Access und MSSQL angefangen. Da hat es sich einfacher gezeigt, Tabellen mit tbl_ und Abfragen qry_ oder Stored Procedur mit SP_ anzufangen. Daher habe ich das hier auch so getan.
Ich habe mir mal den Teil
angesehen.
Dabei hat die Konsole einen Fehler festgestellt.
Code: Alles auswählen
def connect():
return MySQLdb.connect(host=DB_HOST, port=3307,
user=DB_USER , passwd=DB_PASSWORD, db="Schiessbuch",
cursorclass=MySQLdb.cursors.DictCursor)
Dabei hat die Konsole einen Fehler festgestellt.
BIn das gerade mal am Googln und verstehen.File "SchuetzeAnlegen.py", line 14, in connect
cursorclass=MySQLdb.cursors.DictCursor)
AttributeError: 'module' object has no attribute 'cursors'
Hallo,
ich muss hier leider noch mal fragen.
Warum kommt hierbei die Meldung das der Cursor nicht im Modul ist?
ich muss hier leider noch mal fragen.
Warum kommt hierbei die Meldung das der Cursor nicht im Modul ist?
Code: Alles auswählen
#!/usr/bin/python3
import sys
import RPi.GPIO as gpio
#import MFRC522
import MySQLdb
DB_HOST =
DB_USER =
DB_PASSWORD = "
def connect():
return MySQLdb.connect(host=DB_HOST, port=3307,
user=DB_USER , passwd=DB_PASSWORD, db="Schiessbuch",
cursorclass=MySQLdb.cursors.DictCursor)
Traceback (most recent call last):
File "SchuetzeAnlegen-Forum.py", line 79, in <module>
main()
File "SchuetzeAnlegen-Forum.py", line 62, in main
db = connect()
File "SchuetzeAnlegen-Forum.py", line 14, in connect
cursorclass=MySQLdb.cursors.DictCursor)
AttributeError: module 'MySQLdb' has no attribute 'cursors'
Ich hatte mal folgendes Probiert
Das ging auch, bei der ersten Abfrage, bei der 2. sagte er der Cursor wäre closed
Code: Alles auswählen
def connect():
conn = MySQLdb.connect(host=DB_HOST, port=3307,
user=DB_USER , passwd=DB_PASSWORD, db="Schiessbuch")
return conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
Das ging auch, bei der ersten Abfrage, bei der 2. sagte er der Cursor wäre closed
Du brauchst ein
Das zweite Beispiel, das funktioniert, dürfte daher auch nicht funktionieren.
Code: Alles auswählen
import MySQLdb.cursors
Ok Danke. Das scheint damit zu klappen.
Bekomme aber weiterhin Meldungen...
Bekomme aber weiterhin Meldungen...
Traceback (most recent call last):
File "SchuetzeAnlegen-Forum2.py", line 80, in <module>
main()
File "SchuetzeAnlegen-Forum2.py", line 65, in main
benutzer_anzeigen(db)
File "SchuetzeAnlegen-Forum2.py", line 19, in benutzer_anzeigen
with db as cursor:
AttributeError: __exit__