DjangoUnicodeDecodeError при сохранении данных pickle'd - PullRequest
3 голосов
/ 26 марта 2010

У меня есть простой dict объект, который я пытаюсь сохранить в базе данных после того, как он прошел через pickle.Кажется, что Джанго не любит пытаться закодировать эту ошибку.Я проверил с MySQL, и запрос даже не дошел до того, как выдает ошибку, поэтому я не верю, что это проблема.dict, который я храню, выглядит следующим образом:

{
    'ordered': [
        {   'value': u'First\xd1ame Last\xd1ame',
            'label': u'Full Name' },
        {   'value': u'123-456-7890',
            'label': u'Phone Number' },
        {   'value': u'user@nowhere.org',
            'label': u'Email Address' } ],
    'cleaned_data': {
        u'Phone Number': u'123-456-7890',
        u'Full Name': u'First\xd1ame Last\xd1ame',
        u'Email Address': u'user@nowhere.org' },
    'post_data': <QueryDict: {
        u'Phone Number': [u'1234567890'],
        u'Full Name_1': [u'Last\xd1ame'],
        u'Full Name_0': [u'First\xd1ame'],
        u'Email Address': [u'user@nowhere.org'] }>,
    'user': <User: itis>
}

Выдается ошибка:

Кодек utf8 не может декодировать байты в позиции 52-53: неверные данные.

Позиция 52-53 - это первый экземпляр \xd1 (С) в выбранных данных.

До сих пор я копался в StackOverflow и нашел несколько вопросов, где кодировка базы данных для объектов была неправильной.Это не помогает мне, потому что нет запроса MySQL еще.Это происходит перед базой данных.Google также мало помогал при поиске ошибок Юникода в маринованных данных.

Вероятно, стоит упомянуть, что если я не использую С, этот код работает нормально.

Ответы [ 3 ]

3 голосов
/ 29 марта 2010

Большое спасибо @prometheus, я нашел решение для этого. По сути, вы можете использовать base64 для кодирования вывода pickle.dumps() перед его подключением к базе данных. Затем вы можете развернуться и использовать base64 для декодирования выходных данных базы данных, прежде чем передать их в pickle.loads().

Мой код теперь выглядит так:

## Put the information into the database:
self.raw_data = base64.b64encode(pickle.dumps(data))

## Get the information out of the database:
return pickle.loads(base64.b64decode(self.raw_data))

Опять же, спасибо @ Прометей.

2 голосов
/ 27 марта 2010

Это известная проблема, и об этом говорили на Python bug-tracker :

Я столкнулся с этой проблемой сегодня, когда записывал структуры данных Python в база данных. Только ASCII безопасен в этой ситуации. Я поняла Python документирует, что протокол 0 был только для ASCII.

Сейчас я использую pickle + base64, однако это затрудняет отладку.

В любом случае, я думаю, что в документах должно быть четко сказано, что протокол 0 не Только для ASCII, потому что это важно в мире Python. Например, Я видел эту проблему, потому что Django делает неявное преобразование Unicode () с моим вводом, который не с ASCII.

1 голос
/ 27 июля 2011

Не вижу в этом необходимости. Обычно должна быть возможность хранить любые двоичные данные в базе данных.

Хуже проблема заключается в том, что травление небезопасно - если база данных может получить свои данные откуда угодно, она может получить данные злонамеренного травления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...