繁体   English   中英

Python 2.7 和 3.8.0 兼容的 django-redis 序列化程序

[英]Python 2.7 and 3.8.0 compatible django-redis serializer

我有两台服务器运行,一台在 python2.7 上运行,另一台在 python3.8 上运行。

对于两台服务器,我们都有通用的 Django 缓存服务器。

python2.7 服务器正在 Django-cache 和 python3.8 中设置缓存,试图读取这个抛出一个错误说

文件“/usr/local/bin/python-3.8.0/lib/python3.8/site-packages/django_redis/serializers/pickle.py”,第 35 行,在加载中返回 pickle.loads(value) UnicodeDecodeError: ' ascii' 编解码器无法解码位置 1 中的字节 0xe5:序号不在范围内(128)

我已经阅读了以下带有相同问题链接的帖子

我的目标是能够从两个版本的 python 读取和读取公共 django-cache。

python 2.7默认str编码是ASCII而 3.x 的默认值是utf-8所以你需要考虑这一点。

如果仔细观察,这不是 Redis 问题,而是编码问题,因此出现错误消息:

UnicodeDecodeError: 'ascii' 编解码器无法解码字节

要解决这个问题,你必须在你的 python 2.7 程序中将默认编码设置为utf-8

import sys  

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

这里有关于 python 编码转换问题的更多细节: How to fix UnicodeDecoderError

对我有用的解决方案是我们在 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' 你可以得到字节,否则你会得到一个字符串。

以及settings.py cache config的以下行。

'SERIALIZER':'file.location.CustomPickleSerializer'中。


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.
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM