TypeError: execute() takes at most 4 arguments (238 given)

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
MaxL
User
Beiträge: 10
Registriert: Freitag 13. Februar 2015, 18:51

Hallo zusammen,

ich möchte einige Ergebnisse in eine MySQL-Datenbank speichern.

Code: Alles auswählen

sql = "INSERT INTO data_v4 \
        (br1, br2, br3, "", br5, br6, br7, br8, br9, br10) \
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s),\
        [br1, br2, br3, "", br5, br6, br7, br8, br9, br10]"
   cursor.execute(*sql)
Hinter "" verbirgt sich die automatisch der primary key ...

Dabei erhalte ich folgende Fehlermeldung:
Traceback (most recent call last):
File "C:/Python27/max_codes/br_V11.py", line 114, in <module>
cursor.execute(*sql)
TypeError: execute() takes at most 4 arguments (238 given)
Wer kann mir weiterhelfen?
Dank und Gruß
Max.
BlackJack

@MaxL: `execute()` erwartet an der Stelle *zwei* Argumente: Die SQL-Anweisung als erstes Argument und eine Sequenz, zum Beispiel eine Liste, mit den Werten als zweites Argument. Du übergibst da eine Sequenz, nämlich eine Zeichenkette mit *-Syntax, also jedes Zeichen der Zeichenkette als eigenes Argument.

Das nächste Problem wird dann die Angabe der Spaltennamen sein, da hast Du "" stehen, das geht natürlich nicht. Du kannst eine leere Zeichenkette als Wert angeben, wenn das ein erlaubter Wert für die betreffende Spalte ist, aber nicht als *Namen*.

Die Namen von Tabelle und Spalten sind unglaublich schlecht gewählt.
MaxL
User
Beiträge: 10
Registriert: Freitag 13. Februar 2015, 18:51

Hallo BlackJack,
besten Dank für Deine Antwort. Aber so wirklich weitergeholfen hat sie mir leider nicht.
Wenn ich Dich richtig verstanden habe, ist %s nicht korrekt (hier meine Quelle, die mich auf den Trichter gebracht hat: http://www.python-forum.de/viewtopic.php?f=23&t=31345, siehe Thread von Sirius3 ...)

Wenn ich schreibe:

Code: Alles auswählen

    sql = "INSERT INTO data_v8 \
        (metades, metakeys) \
        VALUES (%s, %s);", \
        metades, metakeys 
    cursor.execute(sql)
    connection.commit()
bekomme ich folgende Meldung:
Traceback (most recent call last):
File "C:\Python27\max_codes\scraping_V13.py", line 118, in <module>
cursor.execute(sql)
File "c:\python27\lib\site-packages\mysql\connector\cursor.py", line 483, in execute
stmt = operation.encode(self._connection.python_charset)
AttributeError: 'tuple' object has no attribute 'encode'
Wenn ich nun - um Encoding-Probleme zu umgehn - das gleiche mit *sql verwende:

Code: Alles auswählen

cursor.execute(*sql)
... Bekomme ich folgende Fehlermeldung:
Traceback (most recent call last):
File "C:\Python27\max_codes\check_V13.py", line 113, in <module>
cursor.execute(*sql)
TypeError: execute() takes at most 4 arguments (11 given)
Selbst wenn ich jetzt konkrete Werte eingebe, habe ich ein Problem:

Code: Alles auswählen

sql = "INSERT INTO data_v8 \
        (metades, metakeys) \
        VALUES ('metades', 'metakeys')"
    cursor.execute(*sql)
    connection.commit()
Auch hier bekomme ich wieder die gleiche Meldung:
Traceback (most recent call last):
File "C:\Python27\max_codes\check_V13.py", line 112, in <module>
cursor.execute(*sql)
TypeError: execute() takes at most 4 arguments (207 given)
Nehme ich das Sternchen wieder raus, läuft alles wunderbar. Nur das Lesen der Datensätze funktioniert nicht ...
Traceback (most recent call last):
File "C:\Python27\max_codes\check_mysql_datensaetze_anzeigen.py", line 20, in <module>
(str(data[0])) + ", " +(str(data[1]))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 4-5: ordinal not in range(128)
PS1: die leere Zeichenkette hatte ich für den automatisch zu vergebenden Primary Key von MySQL gesetzt. Wie ich aber jetzt gelernt habe, muss/darf ich diesen hier nicht aufführen, also habe ich ihn nun weggelassen.

--> ich vermute also, dass ich da (zusätzlich) ein encoding-Problem habe ...

Ideen? (und sorry für die blöden Anfänger-Fragen ...)
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

@MaxL: beim Programmieren kommt man mit Raten nicht sehr weit, wie Du gerade merkst. Wenn Du in die Dokumentation schaust, seht da zur execute-Methode:
.execute ( operation [, parameters ])
Prepare and execute a database operation (query or command).

Parameters may be provided as sequence or mapping and will be bound to variables in the operation.
Das bedeutet also, execute erwartet 2 Parameter, einen String und eine Sequenz. Also weder 1 Tuple, noch 208 Strings. Die *-Magie solltest Du auch erst einsetzen, wenn Du verstanden hast, was Parameter sind, Backslash ganz vermeiden, weil man meist gut mit Klammern arbeiten kann und Strings nie per Backslash in mehrere Zeilen aufteilen, weil das niemand mehr lesen kann.
MaxL
User
Beiträge: 10
Registriert: Freitag 13. Februar 2015, 18:51

Hallo zusammen,
vielen Dank fürs Kopfwaschen. Habe mir die Dokumentation angeschaut. Läuft. Zumindest an dieser Stelle ... Das nächste Problem kommt gleich in einer neuen Frage ...
Dank und Gruß
Max.
Antworten