2010-03-26 4 views
3

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

{ 
    'ordered': [ 
     { 'value': u'First\xd1ame Last\xd1ame', 
      'label': u'Full Name' }, 
     { 'value': u'123-456-7890', 
      'label': u'Phone Number' }, 
     { 'value': u'[email protected]', 
      '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'[email protected]' }, 
    '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'[email protected]'] }>, 
    'user': <User: itis> 
} 

ошибка, выкинет является: кодек

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

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

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

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

+0

Возможно, это не относится к травлению как таковой, и может быть просто ошибкой в ​​кодировке Unicode. Это может помочь http://www.amk.ca/python/howto/unicode –

+0

Что может заставить вас поверить, что это может быть ошибка в unicode?Я довольно новичок в работе с международными персонажами, но все, кажется, закодировано прямо на моем глазу. –

ответ

3

Огромное спасибо @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)) 

Опять же, спасибо @prometheus.

2

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

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

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

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

+0

Если вы хотите переработать ответ, который я разместил, я бы скорее дал вам репутацию для поиска ответа. –

+0

Я в порядке, спасибо. Это в основном код, который я использую сам. – nikola

1

Я не вижу необходимости в этом. Как правило, должно быть возможно хранить любые двоичные данные в базе данных.

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

Смежные вопросы