Как да накарам Python 3 да обработва правилно unicode низове от MongoDB?

Използвам Windows 7 64-bit, Python 3, MongoDB и PyMongo. Знам, че в Python 3 всички низове са unicode. Също така знам, че MongoDB съхранява всички низове като unicode. Така че не разбирам защо, когато изтегля документ от моята база данни, където стойността на определено поле е "C:\Some Folder\E=mc².xyz", Python третира този низ като "C:\Some Folder\ E=mc².xyz". Не просто се отпечатва по този начин; os.path.exists() връща False. Сега, сякаш това не е достатъчно объркващо, ако запазя низа в текстов файл и след това го отворя с кодиране, изрично зададено на "utf-8", низът се появява правилно и os.path.exists() връща True. Какво не е наред и как да го поправя?

Редактиране: Ето малко код, който току-що написах, за да демонстрирам моя проблем:

from pymongo import MongoClient

db = MongoClient().test_db
orig_doc = {'string': 'E=mc²'}
_id = db.test_col.insert(orig_doc)
new_doc = db.test_col.find_one(_id)
print(new_doc['string'])

>>> E=mc²

Както можете да видите, работи точно както трябва! Така сега осъзнавам, че трябва да съм се объркал, когато мигрирах от PostgreSQL. Сега просто трябва да оправя струните. Знам, че е възможно, но трябва да има по-добър начин от записването на низовете в текстов файл и след това четенето им обратно. Можех да направя това, точно както направих в предишното си тестване, но просто не изглежда като правилния начин.


person Steohawk    schedule 11.11.2014    source източник
comment
Можете ли да включите някакъв код? Изглежда, че ви липсва настройка или извикване, което указва кодирането. Изглежда, че наистина нищо не се обърка, вие само получавате обратно данните в неправилно кодиране.   -  person Simeon Visser    schedule 12.11.2014


Отговори (1)


Не можете да съхранявате Unicode. Това е концепция. MongoDB трябва да използва кодиране на Unicode и изглежда като UTF-8. Низовете на Python 3 Unicode се съхраняват вътрешно като едно от редица кодировки в зависимост от съдържанието на низа. Това, което имате, е низ, декодиран в Unicode с грешно кодиране:

>>> s='"C:\Some Folder\E=mc².xyz"'  # The invalid decoding.
>>> print(s)
"C:\Some Folder\E=mc².xyz"
>>> print(s.encode('latin1').decode('utf8'))  # Undo the wrong decoding, and apply the right one.
"C:\Some Folder\E=mc².xyz"

Няма достатъчно информация, която да ви каже как да четете правилно MondoDB, но това трябва да ви помогне.

person Mark Tolonen    schedule 12.11.2014
comment
Отговорът ви дойде точно преди да завърша редактирането на публикацията си. Току-що тествах вашето решение и то работи! Благодаря много! - person Steohawk; 12.11.2014