Die Fehlermeldung
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2026'
in position 35: ordinal not in range(256)
scheint anzuzeigen, dass irgendein Python-Sprachcode versucht, das Zeichen \u2026
zu konvertieren in eine Latin-1 (ISO8859-1) Zeichenfolge, und es schlägt fehl. Nicht überraschend, dieses Zeichen ist U+2026 HORIZONTAL ELLIPSIS
, das in ISO8859-1 kein einziges äquivalentes Zeichen hat.
Sie haben das Problem behoben, indem Sie die Abfrage ?charset=utf8
hinzugefügt haben in Ihrem SQLAlchemy-Verbindungsaufruf:
import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table
db = create_engine('mysql://user:[email protected]/db?charset=utf8')
Der Abschnitt Datenbank-URLs
der SQLAlchemy-Dokumentation sagt uns, dass eine URL, die mit mysql
beginnt gibt einen MySQL-Dialekt an, der den mysql-python
verwendet Fahrer.
Der folgende Abschnitt, Benutzerdefinierte DBAPI connect()-Argumente , teilt uns mit, dass Abfrageargumente an die zugrunde liegende DBAPI übergeben werden.
Also, was macht der mysql-python
Treibermarke eines Parameters {charset:'utf8'}
? Abschnitt Funktionen und Attribute
ihrer Dokumentation sagt von charset
Attribut "...Falls vorhanden, wird der Verbindungszeichensatz auf diesen Zeichensatz geändert, wenn sie nicht gleich sind."
Um herauszufinden, was der Verbindungszeichensatz bedeutet, wenden wir uns an 10.1.4. Verbindungszeichensätze und Sortierungen des MySQL 5.6-Referenzhandbuchs. Um es kurz zu machen, MySQL kann eingehende Abfragen als eine Codierung interpretieren lassen, die sich vom Zeichensatz der Datenbank und von der Codierung der zurückgegebenen Abfrageergebnisse unterscheidet.
Da die von Ihnen gemeldete Fehlermeldung eher wie eine Python- als eine SQL-Fehlermeldung aussieht, spekuliere ich, dass etwas in SQLAlchemy oder mysql-python versucht, die Abfrage in eine Standardverbindungscodierung von latin-1
bevor Sie es senden. Das löst den Fehler aus. Allerdings ist die Abfragezeichenfolge ?charset=utf8
in Ihrem connect()
call ändert die Verbindungskodierung und die U+2026 HORIZONTAL ELLIPSIS
durchkommen kann.
Aktualisierung: Sie fragen auch:"Wenn ich die Zeichensatzoption entferne und dann die Beschreibung mit .encode('cp1252') codiere, wird sie problemlos durchgehen. Wie kann eine Ellipse mit cp1252, aber nicht mit Unicode durchkommen?"
Die Codierung cp1252
hat
ein horizontales Auslassungszeichen beim Bytewert \x85
. Somit ist es möglich, einen Unicode-String zu kodieren, der U+2026 HORIZONTAL ELLIPSIS
enthält in cp1252 ohne Fehler.
Denken Sie auch daran, dass Unicode-Strings und Byte-Strings in Python zwei verschiedene Datentypen sind. Es ist vernünftig zu spekulieren, dass MySQLdb die Richtlinie hat, nur Byte-Strings über eine SQL-Verbindung zu senden. Somit würde es eine als Unicode-String empfangene Abfrage in einen Byte-String codieren, aber eine als Byte-String empfangene Abfrage allein lassen. (Das ist Spekulation, ich habe mir den Quellcode nicht angesehen.)
In dem von Ihnen geposteten Traceback zeigen die letzten beiden Zeilen (am nächsten an der Stelle, an der der Fehler auftritt) die Methodennamen literal
, gefolgt von unicode_literal
. Das stützt tendenziell die Theorie, dass MySQLdb die empfangene Abfrage als Unicode-String in einen Byte-String kodiert.
Wenn Sie die Abfragezeichenfolge selbst codieren, umgehen Sie den Teil von MySQLdb, der diese Codierung anders macht. Beachten Sie jedoch, dass, wenn Sie die Abfragezeichenfolge anders codieren, als der MySQL-Verbindungszeichensatz fordert, Sie eine Codierungsabweichung haben und Ihr Text wahrscheinlich falsch gespeichert wird.