在redis中保存unicode,但获取

2024-05-21 01:25:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用mongodb和redis,redis是我的缓存。

我正在用redis py缓存mongodb对象:

obj in mongodb: {u'name': u'match', u'section_title': u'\u6d3b\u52a8', u'title': 
u'\u6bd4\u8d5b', u'section_id': 1, u'_id': ObjectId('4fb1ed859b10ed2041000001'), u'id': 1}

使用hgetall(key,obj)从redis获取的obj是:

{'name': 'match', 'title': '\xe6\xaf\x94\xe8\xb5\x9b', 'section_title': 
'\xe6\xb4\xbb\xe5\x8a\xa8', 'section_id': '1', '_id': '4fb1ed859b10ed2041000001', 'id': '1'}

如您所见,从缓存中获取的obj是str而不是unicode,因此在我的应用程序中,存在如下错误:“ascii”编解码器无法解码位置12中的字节0xe6:序号不在范围(128)内

有人能给点建议吗?谢谢你


Tags: 对象nameinpyredisidobjtitle
3条回答

更新,对于全局设置,请选中jmoz's answer

如果使用的是第三方库,如django-redis,则可能需要指定自定义的ConnectionFactory

class DecodeConnectionFactory(redis_cache.pool.ConnectionFactory):
    def get_connection(self, params):
        params['decode_responses'] = True
        return super(DecodeConnectionFactory, self).get_connection(self, params)

假设您使用的是redis py,那么最好传递str,而不是unicode到redis,或者*set命令的Redis will encode it automatically,通常是in UTF-8。对于*get命令,Redis不知道值的形式类型,只能直接返回str中的值。

因此,正如丹尼斯所说,将对象存储到Redis的方式至关重要。您需要将该值转换为str,以使Redis层对您透明。

另外,set the default encoding to UTF-8而不是使用ascii

我想我已经发现了这个问题。读完这篇文章后,我不得不明确地从redis中解码,这是一个痛苦,但有效。

我无意中发现了一篇博客文章,作者的输出都是unicode字符串,与我的obv不同。

StrictRedis.__init__中有一个参数decode_responses,默认为Falsehttps://github.com/andymccurdy/redis-py/blob/273a47e299a499ed0053b8b90966dc2124504983/redis/client.py#L446

在construct上传入decode_responses=True,对我来说这解决了OP的问题。

对于每个字符串,您可以使用decode函数将其转换为utf-8格式,例如,如果代码中的title字段:

In [7]: a='\xe6\xaf\x94\xe8\xb5\x9b'

In [8]: a.decode('utf8')
Out[8]: u'\u6bd4\u8d5b'

相关问题 更多 >