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.