MySQLdb: INSERT

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
gerald
User
Beiträge: 3
Registriert: Sonntag 5. Juli 2009, 21:45

Hallo!

Ich probiere gerade einzelne Zeilen in eine MySQL-Tabelle einzufügen, stoße dabei aber auf einige Probleme :?

Code: Alles auswählen

import cmd
import MySQLdb
import getpass

db = MySQLdb.connect("localhost", "benutzername", "password", "datenbank")
c = db.cursor()

class ManagementKonsole(cmd.Cmd):

    def __init__(self):
        cmd.Cmd.__init__(self)
        self.prompt = ">>> "

    def do_adduser(self, prm):
        username = raw_input("Username: ")
        password = getpass.getpass("Password: ")

        c.execute('''
                INSERT INTO login (id, username, password)
                VALUES (%(id)s, %(username)s), %(password)s
                ''', {
                'id': None,
                'username': username,
                'password': password
                })

    def do_showuser(self, prm):
        weitere Anweisungen

    def do_exit(self, prm):
        return True

    def do_quit(self, prm):
        return True

konsole = ManagementKonsole()
konsole.cmdloop()
Speziell geht es bei mir um die Zeile "def do_adduser(self, prm):". Dort erhalte ich folgende Fehlermeldung:
gerald@lisa:~/verwaltung$ python console.py
>>> adduser
Username: gerald
Password: verdeckt eingegebenes Kennwort dank getpass ;-)
Traceback (most recent call last):
File "console.py", line 39, in <module>
konsole.cmdloop()
File "/usr/lib/python2.5/cmd.py", line 142, in cmdloop
stop = self.onecmd(line)
File "/usr/lib/python2.5/cmd.py", line 219, in onecmd
return func(arg)
File "console.py", line 24, in do_adduser
'password': password
File "/var/lib/python-support/python2.5/MySQLdb/cursors.py", line 166, in execute
self.errorhandler(self, exc, value)
File "/var/lib/python-support/python2.5/MySQLdb/connections.py", line 35, 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 ''test'' at line 2")
Ich verwende ein Debian lenny mit MySQLdb in jeweils aktuellem Stand.
Weiß einer bei meinem Problem weiter?

Schönen Abend noch,
gerald
BlackJack

Tja, die Fehlermeldung sagt, dass die SQL-Syntax fehlerhaft ist. Das ist sie auch in der Tat. Schau mal wo die schliessende Klammer zu der öffnenden gleich nach 'VALUES' ist.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Ich habe das Gefühl, du versuchst SQLAlchemy Console (deines ist an MySQL gebunden und hat keine farbige Ausgabe) nachzubauen.
gerald
User
Beiträge: 3
Registriert: Sonntag 5. Juli 2009, 21:45

Vielen Dank erstmal für die Antworten!
BlackJack hat geschrieben:Tja, die Fehlermeldung sagt, dass die SQL-Syntax fehlerhaft ist. Das ist sie auch in der Tat. Schau mal wo die schliessende Klammer zu der öffnenden gleich nach 'VALUES' ist.
Okay, das ist aus der Fehlermeldung ersichtlich, aber den Fehler habe ich daraus trotzdem nicht gefunden ;-)
derdon hat geschrieben:Ich habe das Gefühl, du versuchst SQLAlchemy Console (deines ist an MySQL gebunden und hat keine farbige Ausgabe) nachzubauen.
Kann gut sein, ich habe halt nach allen möglichen gesucht, daher will ich nicht ausschließen, dass der Ansatz komplett falsch ist.

Ich habe jetzt aus MySQLdb User's Guide das Beispiel

Code: Alles auswählen

c.executemany(
      """INSERT INTO breakfast (name, spam, eggs, sausage, price)
      VALUES (%s, %s, %s, %s, %s)""",
      [
      ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ),
      ("Not So Much Spam Plate", 3, 2, 0, 3.95 ),
      ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )
      ] )
herausgesucht und versucht anzupassen:

Code: Alles auswählen

        c.execute(
                """INSERT INTO login (id, username, password)
                VALUES (%s, %s, %s)""",
                [
                ("", username, password )
                ] )
Aber auch dabei erhalte ich Fehlermeldungen:
>>> adduser
Username: gerald
Password:
Traceback (most recent call last):
File "console.py", line 37, in <module>
konsole.cmdloop()
File "/usr/lib/python2.5/cmd.py", line 142, in cmdloop
stop = self.onecmd(line)
File "/usr/lib/python2.5/cmd.py", line 219, in onecmd
return func(arg)
File "console.py", line 22, in do_adduser
("", username, password )
File "/var/lib/python-support/python2.5/MySQLdb/cursors.py", line 151, in execute
query = query % db.literal(args)
TypeError: not enough arguments for format string
Mir ist leider überhaupt nicht klar, wo der Fehler in Zeile 22 stecken soll (das ist bei mir --("", username, password )--) Hat vielleicht noch jemand eine Idee?

EDIT: Vielleicht ist es ja ("", nur habe ich dafür ansonsten keine andere Lösung, None brachte die selbe Fehlermeldung. Die Spalte id in der Datenbank ist mit auto_increment versehen, d.h. die laufende Nummer soll automatisch eingesetzt werden.
Benutzeravatar
sehbaer
User
Beiträge: 39
Registriert: Sonntag 30. März 2008, 17:26
Wohnort: Kölle

Autoincrement Spalten weist man keine Werte zu. Auch kein "" oder sowas. Dafür ist es ja Autoincrement. Einfach die Zuweisung auf id entfernen.
...es sind ganz bestimmt mehr Nullen als Einsen.
BlackJack

@gerald: `execute()` != `executemany()`.
gerald
User
Beiträge: 3
Registriert: Sonntag 5. Juli 2009, 21:45

sehbaer hat geschrieben:Autoincrement Spalten weist man keine Werte zu. Auch kein "" oder sowas. Dafür ist es ja Autoincrement. Einfach die Zuweisung auf id entfernen.
Ah okay, das ist warscheinlich noch eine Angewohnheit aus PHP-Zeiten, da habe ich es so gemacht und es hat auch so funktioniert ;-)
BlackJack hat geschrieben:@gerald: `execute()` != `executemany()`.
Hm, dann habe ich die Doku zu MySQLdb falsch verstanden, ich habe gedacht, dass man execute() bei einem Datensatz und executemany() bei mehreren Datensätzen nutzt. Ich habe nun executemany() verwendet und von sehbaer den Tipp mit auto increment beachtet. Erster Erfolg: Ich erhalte keine Fehlermeldungen mehr, aber trotzdem wird nichts in die Tabelle geschrieben :shock:

Zur Vollständigkeit nochmal der Code:

Code: Alles auswählen

import cmd
import MySQLdb
import getpass

db = MySQLdb.connect("localhost", "username", "password", "datenbank")
c = db.cursor()

class ManagementKonsole(cmd.Cmd):

    def __init__(self):
        cmd.Cmd.__init__(self)
        self.prompt = ">>> "

    def do_adduser(self, prm):
        username = raw_input("Username: ")
        password = getpass.getpass("Password: ")

        c.executemany(
                """INSERT INTO login (username, password)
                VALUES (%s, %s)""",
                [
                (username, password )
                ] )

    def do_showusers(self, prm):
        username = raw_input("Username: ")
        c.execute("SELECT * FROM login WHERE username = %s", (username,))
        print c.fetchall()

    def do_exit(self, prm):
        return True

    def do_quit(self, prm):
        return True

konsole = ManagementKonsole()
konsole.cmdloop()
EDIT: Ich sehe, dass die ID aus auto_increment steigt, das heißt, dass diese schonmal richtig übermittelt wird...
BlackJack

@gerald: Deine Beschreibung der beiden Methoden ist schon richtig, aber Du hast dann versucht `execute()` mit mehreren Datensätzen zu benutzen. Beziehungsweise eigentlich nur mit einem, dem aber dann in einer Liste, so wie Du das jetzt mit `executemany()` machst. Was unsinnig ist, wenn da sowieso immer nur ein Datensatz steht.
Antworten