Chybová zpráva
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2026'
in position 35: ordinal not in range(256)
Zdá se, že to naznačuje, že se nějaký kód jazyka Python pokouší převést znak \u2026
do řetězce Latin-1 (ISO8859-1) a selhává. Není divu, že tato postava je U+2026 HORIZONTAL ELLIPSIS
, který nemá v ISO8859-1 jediný ekvivalentní znak.
Problém jste vyřešili přidáním dotazu ?charset=utf8
ve volání připojení SQLAlchemy:
import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table
db = create_engine('mysql://user:[email protected]/db?charset=utf8')
Sekce Adresy URL databáze
dokumentace SQLAlchemy nám říká, že URL začínající mysql
označuje dialekt MySQL pomocí mysql-python
řidič.
Následující část, Vlastní DBAPI argumenty connect() , nám říká, že argumenty dotazu jsou předány základnímu DBAPI.
Co tedy znamená mysql-python
ovladač vytvoří parametr {charset: 'utf8'}
? Sekce Funkce a atributy
jejich dokumentace říká o charset
atribut "...Pokud existuje, znaková sada připojení bude změněna na tuto znakovou sadu, pokud nejsou stejné."
Chcete-li zjistit, co znamená znaková sada připojení, obraťte se na 10.1.4. Připojení znakové sady a řazení referenční příručky MySQL 5.6. Abych to zkrátil, MySQL může interpretovat příchozí dotazy jako kódování odlišné od znakové sady databáze a odlišné od kódování vrácených výsledků dotazu.
Protože chybová zpráva, kterou jste nahlásili, vypadá spíše jako Python než jako chybová zpráva SQL, budu spekulovat, že se něco v SQLAlchemy nebo mysql-python pokouší převést dotaz na výchozí kódování připojení latin-1
před odesláním. To je to, co spouští chybu. Řetězec dotazu však ?charset=utf8
ve vašem connect()
volání změní kódování připojení a U+2026 HORIZONTAL ELLIPSIS
je schopen projít.
Aktualizace: také se ptáte:"Pokud odstraním možnost znakové sady a poté zakóduji popis pomocí .encode('cp1252'), projde to v pohodě. Jak je elipsa schopná projít s cp1252, ale ne unicode?"
kódování cp1252
má
znak vodorovné elipsy s hodnotou bajtu \x85
. Je tedy možné zakódovat řetězec Unicode obsahující U+2026 HORIZONTAL ELLIPSIS
do cp1252 bez chyby.
Pamatujte také, že v Pythonu jsou řetězce Unicode a bajtové řetězce dva různé datové typy. Je rozumné spekulovat, že MySQLdb může mít politiku odesílání pouze bajtových řetězců přes SQL připojení. Dotaz přijatý jako řetězec Unicode by tedy zakódoval do bajtového řetězce, ale dotaz přijatý jako bajtový řetězec by ponechal sám. (Toto je spekulace, nedíval jsem se na zdrojový kód.)
Ve zpětném sledování, které jste zveřejnili, jsou na posledních dvou řádcích (nejblíže místu, kde došlo k chybě) uvedeny názvy metod literal
, následovaný unicode_literal
. To podporuje teorii, že MySQLdb kóduje dotaz, který obdrží, jako řetězec Unicode do bajtového řetězce.
Když sami kódujete řetězec dotazu, obcházíte část MySQLdb, která toto kódování provádí jinak. Všimněte si však, že pokud zakódujete řetězec dotazu jinak, než vyžaduje znaková sada připojení MySQL, budete mít nesoulad v kódování a váš text bude pravděpodobně uložen špatně.