Krótko mówiąc, należy zmienić:
Unicode(500)
do: (. Python 2 kod poniżej, ale zasady trzymać w python 3; tylko niektóre wyjścia będą się różnić)
Unicode(500, unicode_errors='ignore', convert_unicode='force')
Co się dzieje, kiedy dekodujesz testowanie, skarży się, że nie można dekodować testu bytowego z powodu błędu, który widziałeś.
>>> u = u'ABCDEFGH\N{TRADE MARK SIGN}'
>>> u
u'ABCDEFGH\u2122'
>>> print(u)
ABCDEFGH™
>>> s = u.encode('utf-8')
>>> s
'ABCDEFGH\xe2\x84\xa2'
>>> truncated = s[:-1]
>>> truncated
'ABCDEFGH\xe2\x84'
>>> truncated.decode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/cliffdyer/.virtualenvs/edx-platform/lib/python2.7/encodings/utf_8.py",
line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 8-9: unexpected
end of data
Python zapewnia jednak różne opcjonalne tryby obsługi błędów dekodowania. Zgłaszanie wyjątków jest domyślne, ale można również obcinać tekst lub przekształcać zniekształconą część ciągu w oficjalny znak zastępczy Unicode.
>>> trunc.decode('utf-8', errors='replace')
u'ABCDEFGH\ufffd'
>>> trunc.decode('utf-8', errors='ignore')
u'ABCDEFGH'
To jest dokładnie to, co dzieje się w ramach obsługi kolumn.
Patrząc na klasy Unicode i String w sqlalchemy/sql/sqltypes.py, wygląda na to, że istnieje argument unicode_errors
, który można przekazać do konstruktora, który przekazuje jego wartość do argumentu błędów kodera. Istnieje również uwaga, że musisz ustawić convert_unicode='force'
, aby działało.
W ten sposób Unicode(500, unicode_errors='ignore', convert_unicode='force')
powinien rozwiązać twój problem, jeśli jesteś w porządku z obcięciem końce danych.
Jeśli masz pewną kontrolę nad bazą danych, powinieneś być w stanie zapobiec temu problemowi w przyszłości, definiując bazę danych, aby użyć zestawu znaków utf8mb4
. (Nie używaj po prostu utf8
, lub nie powiedzie się na czterobajtowych utf8 znakach, wliczając w to większość emoji). Wtedy będziesz mieć gwarancję, że masz ważny utf-8 zapisany i zwrócony z twojej bazy danych.
Wygląda na to, że cokolwiek wykonano, obcięcie było tak nieświadome zestawu znaków, co było oryginalnym błędem. Możesz spróbować przekonwertować kolumnę MySQL na binarną, a następnie z powrotem na UTF8-I * myślę, że powinna wymusić zastąpienie niekompletnych znaków przez '?'. – eggyal
Możesz zacząć od włączenia pełnego śledzenia; w ten sposób możemy przynajmniej zdiagnozować, czy dekodowanie może być wykonane w innym miejscu, czy też można je skonfigurować tak, aby zajęło się procedurą obsługi błędów. –