valueInserted = zlib.compress('a') = 'x\x9cK\x04\x00\x00b\x00b'
Обратите внимание, что это объект str . Вы говорите, что «вставили его в столбец mysql типа blob, используя кодировку utf-8». Поскольку сжатая строка является двоичной, а не текстовой, столбец blob - это соответствующий тип столбца, но ЛЮБОЕ кодирование или другое преобразование - очень плохая идея. Вы должны иметь возможность восстанавливать из базы данных ТОЧНО, вплоть до последнего вставленного вами бита, в противном случае распаковка не удастся, либо из-за возникновения ошибки, либо (менее вероятно, но хуже), производящей мусор в режиме без вывода сообщений.
Вы говорите, что возвращаетесь после любого процесса, который вы проходите, вставляя и извлекая его снова:
valueFromSqlColumn = u'x\x9cK\x04\x00\x00b\x00b'
Обратите внимание, что есть только одно крошечное визуальное отличие: «что-то» вместо «чего-то». Это делает его юникодом объектом. Судя по вашим собственным свидетельствам, «возвращается как UTF-8» не правильно. Объект Unicode и объект str, закодированные в utf8, - это не одно и то же.
Угадай 1: вставить в виде необработанной строки, извлечь с декодированием из латиницы 1.
Предположим, что 2: вставить как сжатый код ('latin1'). Кодировать ('utf8'), извлечь с декодированием utf8.
Вы действительно должны понимать процесс вставки и извлечения, включая то, что кодирование и декодирование происходит по умолчанию.
Тогда вам действительно нужно исправить свой код. Однако, тем временем вы, вероятно, можете запутаться в том, что у вас есть.
Обратите внимание:
>>> valueFromSqlColumn = u'x\x9cK\x04\x00\x00b\x00b'
>>> all(ord(char) <= 255 for char in valueFromSqlColumn)
True
Проведите несколько испытаний с более сложным вводом, чем «а». Если, как я полагаю, вы видите, что все символы Юникода имеют порядковый номер в диапазоне (256), то у вас есть простой ключ:
>>> compressed = valueFromSqlColumn.encode('latin1')
>>> compressed
'x\x9cK\x04\x00\x00b\x00b'
>>> zlib.decompress(compressed)
'a'
Почему это работает, потому что кодировка / декодирование Latin1 не меняет порядковый номер. Вы можете восстановить исходное сжатое значение:
>>> compressed2 = ''.join(chr(ord(uc)) for uc in valueFromSqlColumn)
>>> compressed2
'x\x9cK\x04\x00\x00b\x00b'
>>> compressed2 == compressed
True
если вы думаете, что использование .encode ('latin1') слишком похоже на voodoo.
Если вышеперечисленное не работает (т.е. некоторые порядковые номера не находятся в диапазоне (256)), то вам нужно будет создать небольшой исполняемый скрипт, который точно показывает и воспроизводит, как вы сжимаете, вставляя в базу данных и извлекая ее из базы данных ... разбросайте множество print "variable", repr(variable)
вокруг вашего кода, чтобы вы могли видеть, что происходит.