Python 2.7 и 3.8.0 совместимые django -redis сериализатор - PullRequest
0 голосов
/ 28 января 2020

У меня работает два сервера: один работает на python2 .7, а другой на python3 .8.

для обоих серверов у нас есть общий сервер Django -cache.

python2 .7 сервер устанавливает кэш в Django -cache и python3 .8 при попытке прочитать это выдает ошибку:

File "/usr/local/bin/python-3.8.0/lib/python3.8/site-packages/django_redis/serializers/ pickle.py ", строка> 35, в нагрузках возвращает pickle.loads (значение) UnicodeDecodeError: код 'ascii' c не может декодировать байт 0xe5 в позиции 1: порядковый номер не в диапазоне (128)

я уже читал нижеприведенный пост с тем же вопросом ссылка

моя цель здесь состоит в том, чтобы читать и из обеих версий python в общий django -кэш.

Ответы [ 2 ]

0 голосов
/ 29 января 2020

Решение, которое сработало для меня, заключается в том, что мы реализовали собственный сериализатор и сумматор, которые в конфигурации redis_cache.

import six
from django.utils.encoding import force_bytes
from django_redis.serializers.pickle import PickleSerializer

try:
    import cPickle as pickle
except ImportError:
    import pickle


class CcustomPickleSerializer(PickleSerializer):

    def loads(self, value):
        if six.PY3:
            return self._loads_py3(value)
        return super().loads(force_bytes(value))

    def _loads_py3(self, value):
        return pickle.loads(
            force_bytes(value),
            fix_imports=True,
            encoding='latin1'
        )

, если вы используете метод кодирования как 'bytes'. Вы можете получить байты, иначе вы получите строку.

и нижеупомянутую строку в cache config внутри settings.py.

'SERIALIZER':'file.location.CustomPickleSerializer' in.


CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/0',
        'OPTIONS': {
            'KEY_PREFIX': 'personify',
            'SERIALIZER':'file.location.CustomPickleSerializer',
            'PARSER_CLASS': 'redis.connection.HiredisParser',  # Hiredis is WAY faster than redis-py
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'CONNECTION_POOL_KWARGS': {
                'max_connections': 100
            },
            'PICKLE_VERSION': 2,  # Make sure we're using v2 of pickle, which is pretty efficient.
            'SOCKET_CONNECT_TIMEOUT': 5,  # Seconds (timeout for the connection to be established).
            'SOCKET_TIMEOUT': 5,  # Seconds (timeout for read and write operations after the connection is established).
            'IGNORE_EXCEPTIONS': False  # Set to True to act like memcached - i.e. don't raise errors.
        }
    }
}
0 голосов
/ 28 января 2020

По умолчанию str кодировка в python 2.7 равна ASCII, в то время как по умолчанию для 3.x - utf-8, поэтому вы должны это учитывать.

Если вы присмотритесь, это не проблема Redis, это проблема кодирования, поэтому появляется сообщение об ошибке:

UnicodeDecodeError: код 'ascii' c не может декодировать байт

Чтобы решить эту проблему, вы должны установить кодировку по умолчанию utf-8 в вашей программе python 2.7.

import sys  

reload(sys)  
sys.setdefaultencoding('utf8')

Подробнее о проблеме преобразования кодировки python можно узнать здесь: Как исправить UnicodeDecoderError

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