Seite 1 von 2
Datum & SQL
Verfasst: Donnerstag 25. Juli 2013, 13:36
von Joe-Waschl
hi @ll,
habe leider ein kleines problem, und komme nicht weiter,
habe ein kleines skript geschrieben mit dem man adressen verwalten kann,
welche in eine datenbank in mysql gespeichert werden.
bei der funktion "
alle" klappt die formatierung, nur
bei "
namen" nicht
was mache ich falsch?
Code: Alles auswählen
def alle(db):
cur = db.cursor()
#cur.execute("SELECT * FROM Anschrift")
cur.execute("SELECT Anschrift_ID, Name, Nachname, Straße, PLZ, Ort, Telefon, Handy, email, DATE_FORMAT(Geburtstag, '%d.%m.%Y') AS Geburtstag FROM Anschrift;")
for row in cur.fetchall():
print '---------------------'
print 'Nr.: ', row[0]
print 'Name: ', row[1]
print 'Nachname: ', row[2]
print 'Straße: ', row[3]
print 'PLZ: ', row[4]
print 'Ort: ', row[5]
print 'Telefonnr.:', row[6]
print 'Handy: ', row[7]
print 'Email: ', row[8]
print 'Geburtstag:', row[9]
print '----------------------'
def namen(db):
eingabe = str(raw_input('Namen: '))
cur = db.cursor()
#cur.execute("SELECT * FROM Anschrift where Name = %s", (eingabe))
cur.execute("SELECT Anschrift_ID, Nachname, Straße, PLZ, Ort, Telefon, Handy, email, DATE_FORMAT(Geburtstag, '%d.%m.%Y') AS Geburtstag FROM Anschrift where Name = '%s'", (eingabe))
for row in cur.fetchall():
print '---------------------'
print 'Nr.: ', row[0]
print 'Name: ', row[1]
print 'Nachname: ', row[2]
print 'Straße: ', row[3]
print 'PLZ: ', row[4]
print 'Ort: ', row[5]
print 'Telefonnr.:', row[6]
print 'Handy: ', row[7]
print 'Email: ', row[8]
print 'Geburtstag:', row[9]
print '----------------------'
danke und gruß Joe
EDIT:
sry habe das wichtigste vergessen
Code: Alles auswählen
0 = Beenden
1 = alle anzeigen
2 = nach Namen Suchen
3 = Neuer Eintrag
4 = Löschen
Es sind: 1 Einträge vorhanden
eingabe: 2
Namen: Joe
Traceback (most recent call last):
File "/home/user1/.eclipse/org.eclipse.platform_3.7.0_155965261/plugins/org.python.pydev_2.7.1.2012100913/pysrc/pydevd.py", line 1397, in <module>
debugger.run(setup['file'], None, None)
File "/home/user1/.eclipse/org.eclipse.platform_3.7.0_155965261/plugins/org.python.pydev_2.7.1.2012100913/pysrc/pydevd.py", line 1090, in run
pydev_imports.execfile(file, globals, locals) #execute the script
File "/home/user1/workspace/Datenbank/mysql/anschrieft.py", line 129, in <module>
main()
File "/home/user1/workspace/Datenbank/mysql/anschrieft.py", line 116, in main
namen(db)
File "/home/user1/workspace/Datenbank/mysql/anschrieft.py", line 38, in namen
cur.execute("SELECT Anschrift_ID, Nachname, Straße, PLZ, Ort, Telefon, Handy, email, DATE_FORMAT(Geburtstag, '%d.%m.%Y') AS Geburtstag FROM Anschrift where Name = '%s'", (eingabe))
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 159, in execute
query = query % db.literal(args)
TypeError: %d format: a number is required, not str
Re: Datum & SQL
Verfasst: Donnerstag 25. Juli 2013, 14:17
von Madmartigan
Was genau ist denn das Problem, also welchen Fehler erhälst du denn? Ich hab zwar keine wirkliche Erfahrung mit mySQL aber könnte mir vorstellen, dass dein Parameter nicht korrekt formatiert ist. Möglich, dass da eine Liste erwartet wird.
Ohne Fehlermeldung bleibt es aber beim blanken Rumraten.

Re: Datum & SQL
Verfasst: Donnerstag 25. Juli 2013, 18:44
von Joe-Waschl
EDIT
Re: Datum & SQL
Verfasst: Donnerstag 25. Juli 2013, 19:53
von lexaiden
Code: Alles auswählen
cur.execute("SELECT Anschrift_ID, Nachname, Straße, PLZ, Ort, Telefon, Handy, email, DATE_FORMAT(Geburtstag, '%d.%m.%Y') AS Geburtstag FROM Anschrift where Name = '%s'", (eingabe))
Das "eingabe" wird in das %d gepackt, würde ich jetzt mal so behaupten. Du solltest das anders schreiben, z.B. so:
Code: Alles auswählen
cur.execute("SELECT Anschrift_ID, Nachname, Straße, PLZ, Ort, Telefon, Handy, email, DATE_FORMAT(Geburtstag, '%d.%m.%Y') AS Geburtstag FROM Anschrift where Name = '" + str(eingabe) + "'")
Für alle die nur bis hier hin lesen, so gehts, aber so nicht machen. Siehe nächste Beiträge!
Re: Datum & SQL
Verfasst: Donnerstag 25. Juli 2013, 20:40
von BlackJack
@lexaiden: Nein, genau so etwas sollte man *nicht* machen. Das ist eine riesige Sicherheitslücke Benutzereingaben einfach so in eine SQL-Anfrage per Zeichenkettenoperationen zu stecken.
@Joe-Waschl: Du musst in der SQL-Anfrage die '%' schützen die nicht Teil von einem Platzhalter sind. Und statt dem einen Wert musst Du ein Tupel oder eine Liste mit `eingabe` als Element übergeben.
Re: Datum & SQL
Verfasst: Donnerstag 25. Juli 2013, 20:48
von lexaiden
@BlackJack Äh, richtig, ich hab nur die Fehlermeldung gelesen und die eine Zeile vom Code. Hab ich jetzt irgendwie vorrausgesetzt, dass dies keine Rohe Eingabe sein darf (bzw. ungeprüfte), aber steht da ja exakt so im Code...
Aber übersehe ich gerade was, dein Lösungsansatz ist doch genau das gleich und erlaubt SQL-Code für die Eingabe?!
Re: Datum & SQL
Verfasst: Donnerstag 25. Juli 2013, 20:50
von Joe-Waschl
thx, werds gleich probieren
EDIT:
mhhh nur wie schütze ich die % :K
Re: Datum & SQL
Verfasst: Donnerstag 25. Juli 2013, 20:54
von BlackJack
@lexaiden: Klar kann man SQL-Code eingeben, aber der wird vom Datenbankmodul entsprechend escaped, damit er als Wert und nicht als SQL-Ausdruck verwendet wird.
Re: Datum & SQL
Verfasst: Donnerstag 25. Juli 2013, 21:08
von lexaiden
@BlackJack Ach, das macht die "execute" Methode für mich. Sehr schön.
@Joe-Waschl
Note that any literal percent signs in the query string passed to execute() must be escaped, i.e. %%.
Parameter placeholders can only be used to insert column values. They can not be used for other parts of SQL, such as table names, statements, etc.
Quelle:
http://mysql-python.sourceforge.net/MySQLdb.html
Re: Datum & SQL
Verfasst: Freitag 26. Juli 2013, 10:19
von Joe-Waschl
moin,
mit den doppelten prozent zeichen klappts leider auch nicht.
Code: Alles auswählen
namen(db):
liste_eingabe = []
eingabe = raw_input('Namen: ')
liste_eingabe.append(eingabe)
cur = db.cursor()
cur.execute("""SELECT Anschrift_ID, Nachname, Straße, PLZ, Ort, Telefon, Handy, email,
DATE_FORMAT(Geburtstag, '%d.%m.%Y') AS Geburtstag FROM Anschrift where Name = '%%s'""", (liste_eingabe))
#cur.execute("""SELECT Anschrift_ID, Nachname, Straße, PLZ, Ort, Telefon, Handy, email,
#DATE_FORMAT(Geburtstag, '%d.%m.%Y') AS Geburtstag FROM Anschrift where Name = '""" + liste_eingabe + "'")
for row in cur.fetchall():
print '---------------------'
print 'Nr.: ', row[0]
print 'Name: ', row[1]
print 'Nachname: ', row[2]
print 'Straße: ', row[3]
print 'PLZ: ', row[4]
print 'Ort: ', row[5]
print 'Telefonnr.:', row[6]
print 'Handy: ', row[7]
print 'Email: ', row[8]
print 'Geburtstag:', row[9]
print '----------------------'
Fehlermeldung:
Code: Alles auswählen
Traceback (most recent call last):
File "/home/user1/.eclipse/org.eclipse.platform_3.7.0_155965261/plugins/org.python.pydev_2.7.1.2012100913/pysrc/pydevd.py", line 1397, in <module>
debugger.run(setup['file'], None, None)
File "/home/user1/.eclipse/org.eclipse.platform_3.7.0_155965261/plugins/org.python.pydev_2.7.1.2012100913/pysrc/pydevd.py", line 1090, in run
pydev_imports.execfile(file, globals, locals) #execute the script
File "/home/user1/workspace/Datenbank/mysql/anschrieft.py", line 132, in <module>
main()
File "/home/user1/workspace/Datenbank/mysql/anschrieft.py", line 119, in main
namen(db)
File "/home/user1/workspace/Datenbank/mysql/anschrieft.py", line 40, in namen
cur.execute("SELECT Anschrift_ID, Nachname, Straße, PLZ, Ort, Telefon, Handy, email, DATE_FORMAT(Geburtstag, '%d.%m.%Y') AS Geburtstag FROM Anschrift where Name = '%%s'", (liste_eingabe))
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 159, in execute
query = query % db.literal(args)
TypeError: %d format: a number is required, not str
gruß Joe
Re: Datum & SQL
Verfasst: Freitag 26. Juli 2013, 11:23
von BlackJack
@Joe-Waschl: Du hast es ganau an der falschen Stelle gemacht. Nicht beim Platzhalter sondern bei den % wo *kein* Platzhalter stehen soll musst Du verdoppeln, damit die geschützt werden.
Re: Datum & SQL
Verfasst: Freitag 26. Juli 2013, 12:01
von Joe-Waschl
ahh ok thx
irgendwie steh ich auf der leitung
Code: Alles auswählen
cur.execute("""SELECT Anschrift_ID, Nachname, Straße, PLZ, Ort, Telefon, Handy, email,
DATE_FORMAT(Geburtstag, '%%d.%%m.%%Y') AS Geburtstag FROM Anschrift where Name = '%s'""", (liste_eingabe))
Code: Alles auswählen
Traceback (most recent call last):
File "/home/user1/.eclipse/org.eclipse.platform_3.7.0_155965261/plugins/org.python.pydev_2.7.1.2012100913/pysrc/pydevd.py", line 1397, in <module>
debugger.run(setup['file'], None, None)
File "/home/user1/.eclipse/org.eclipse.platform_3.7.0_155965261/plugins/org.python.pydev_2.7.1.2012100913/pysrc/pydevd.py", line 1090, in run
pydev_imports.execfile(file, globals, locals) #execute the script
File "/home/user1/workspace/Datenbank/mysql/anschrieft.py", line 134, in <module>
main()
File "/home/user1/workspace/Datenbank/mysql/anschrieft.py", line 121, in main
namen(db)
File "/home/user1/workspace/Datenbank/mysql/anschrieft.py", line 41, in namen
DATE_FORMAT(Geburtstag, '%%d.%%m.%%Y') AS Geburtstag FROM Anschrift where Name = '%s'""", (liste_eingabe))
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
_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 'Joe''' at line 2")
Re: Datum & SQL
Verfasst: Freitag 26. Juli 2013, 12:17
von BlackJack
@Joe-Waschl: Die ' um den Platzhalter gehören dort nicht hin.
Re: Datum & SQL
Verfasst: Freitag 26. Juli 2013, 12:48
von Joe-Waschl
ok

thx
Code: Alles auswählen
print 'Geburtstag:', row[9]
IndexError: tuple index out of range
:K
Re: Datum & SQL
Verfasst: Freitag 26. Juli 2013, 12:51
von EyDu
Die Fehlermeldung sagt doch schon alles: du versuchst auf das 10. Element von row zuzugreifen, row hat aber keine 10 Elemente.
Re: Datum & SQL
Verfasst: Freitag 26. Juli 2013, 12:58
von Joe-Waschl
habs

thx
Name hatte in der execute... gefehlt
...SELECT Anschrift_ID,
Name, Nachname, Straße, PLZ, Ort, Telefon, Handy, email,
DATE_FORMAT(Geburtstag, '%%d.%%m.%%Y') AS Geburtstag FROM Anschrift where Name = %s...
danke für die hilfe

Re: Datum & SQL
Verfasst: Freitag 26. Juli 2013, 13:20
von BlackJack
@Joe-Waschl: Die beiden Funktionen enthalten zu viel fast identischen Code. So etwas sollte man vermeiden, weil es fehleranfällig ist wenn man mal etwas verändern will oder muss und das dann in jeder „Kopie” machen muss und auch auf die selbe Weise.
Das mit der Liste ist umständlich gelöst. Statt eine leere zu erstellen und dann ein einziges Element anzuhängen hätte man auch gleich eine literale Liste mit `eingabe` als einzigem Element hinschreiben können. Und das auch gleich als Argument beim `execute()`-Aufruf ohne es noch mal an einen Namen binden zu müssen. Die Klammern dort um die `eingabe` beziehungsweise `liste_eingabe` sind unnötig und sollten weggelassen werden.
Re: Datum & SQL
Verfasst: Freitag 26. Juli 2013, 13:36
von Joe-Waschl
habs geändert
Code: Alles auswählen
def namen(db):
eingabe = [raw_input('Namen: ')]
cur = db.cursor()
cur.execute("""SELECT Anschrift_ID, Name, Nachname, Straße, PLZ, Ort, Telefon, Handy, email,
DATE_FORMAT(Geburtstag, '%%d.%%m.%%Y') AS Geburtstag FROM Anschrift where Name = %s""", (eingabe))
for row in cur.fetchall():
print '---------------------'
print 'Nr.: ', row[0]
print 'Name: ', row[1]
print 'Nachname: ', row[2]
print 'Straße: ', row[3]
print 'PLZ: ', row[4]
print 'Ort: ', row[5]
print 'Telefonnr.:', row[6]
print 'Handy: ', row[7]
print 'Email: ', row[8]
print 'Geburtstag:', row[9]
print '----------------------'
Re: Datum & SQL
Verfasst: Dienstag 30. Juli 2013, 15:45
von bfm
Joe-Waschl hat geschrieben:habs geändert
Code: Alles auswählen
def namen(db):
eingabe = [raw_input('Namen: ')]
cur = db.cursor()
cur.execute("""SELECT Anschrift_ID, Name, Nachname, Straße, PLZ, Ort, Telefon, Handy, email,
DATE_FORMAT(Geburtstag, '%%d.%%m.%%Y') AS Geburtstag FROM Anschrift where Name = %s""", (eingabe,))
for row in cur.fetchall():
print '---------------------'
print 'Nr.: ', row[0]
print 'Name: ', row[1]
print 'Nachname: ', row[2]
print 'Straße: ', row[3]
print 'PLZ: ', row[4]
print 'Ort: ', row[5]
print 'Telefonnr.:', row[6]
print 'Handy: ', row[7]
print 'Email: ', row[8]
print 'Geburtstag:', row[9]
print '----------------------'
funktioniert die Abfrage so? Ich würde meinen, dass da hinter 'eingabe' noch das Komma fehlt, so wie ich es bereits geändert habe. Sonst übergibt man dem Platzhalter %s ein e dann ein i, n, g, a, b, e und nicht den Wert der in 'eingabe' gespeichert ist.
lg
Re: Datum & SQL
Verfasst: Dienstag 30. Juli 2013, 15:52
von BlackJack
@bfm: Da gehört weder das Komma noch die Klammern hin, weil Eingabe bereits eine Liste ist.