You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redis创建字符串SET集合读取时返回整数异常排查

问题现象

使用Redis存储SET类型数据时,预期存入'Fred'、'Emmanuel'、'Marcus Aurelius'这类字符串成员,执行SMEMBERS pairs命令读取时,未返回预期的字符串列表,仅返回如下数字字符串:

1) "32"
 2) "39"
 3) "44"
 4) "65"
 5) "69"
 6) "70"
 7) "77"
 8) "91"
 9) "93"
10) "97"
11) "99"
12) "100"
13) "101"
14) "105"
15) "108"
16) "109"
17) "110"
18) "114"
19) "115"
20) "117"

涉及的业务代码如下(基于Django DRF实现):

@api_view(['GET', 'POST'])
def manage_items(request, *args, **kwargs):
    if request.method == 'GET':
        items = []
        count = 0
        for elem in redis_instance.smembers("pairs"):
            items.append(elem.decode("utf-8"))
            count += 1
        response = {
            'count': count,
            'msg': f"Found {count} items.",
            'items': items
        }
        return Response(response, status=200)
    elif request.method == 'POST':
        new_users = request.body
        for i in range(0, len(new_users)):
            redis_instance.sadd('pairs', bytes(str(new_users[i]), "utf-8"))
        response = {
            'msg': f'set contains: {new_users}'
        }
        return Response(response, 201)
问题根因

写入逻辑存在根本性错误:

  1. request.body拿到的是HTTP请求的原始二进制字节串,不是解析后的用户列表。你通过索引new_users[i]遍历字节串时,取到的是每个单独字节对应的ASCII十进制整数值,根本不是完整的用户名。
  2. 返回值里的32(空格)、39(单引号)、44(逗号)、65(大写A)、70(大写F)等,正好是传入请求体原始文本每个字符对应的ASCII码,和存错的内容完全匹配。
  3. 代码全程没有对请求体做结构化解析,相当于把请求报文里每个字符的ASCII码挨个存进了SET,自然读不到预期的用户名。
修复方案

按以下步骤调整即可:

  • 不要直接操作原始request.body字节串,DRF框架会自动解析请求体,直接通过request.data拿到解析后的结构化用户列表即可。
  • 遍历解析后的完整用户列表,将每个用户名字符串直接传入sadd方法,redis-py客户端会自动处理编码转换,不需要手动转bytes。
  • 修复前先执行redis_instance.delete('pairs')清除之前写入的脏数据,避免旧的错误值残留。

修复后的完整代码如下:

@api_view(['GET', 'POST'])
def manage_items(request, *args, **kwargs):
    if request.method == 'GET':
        items = []
        count = 0
        for elem in redis_instance.smembers("pairs"):
            items.append(elem.decode("utf-8"))
            count += 1
        response = {
            'count': count,
            'msg': f"Found {count} items.",
            'items': items
        }
        return Response(response, status=200)
    elif request.method == 'POST':
        # 直接取DRF解析后的结构化数据,适配请求实际传参格式即可
        new_users = request.data
        # 遍历用户名字符串列表直接存入
        for username in new_users:
            redis_instance.sadd('pairs', username)
        response = {
            'msg': f'set contains: {new_users}'
        }
        return Response(response, 201)

注意:如果POST请求传参格式不是JSON,对应调整request.data的取值逻辑即可,核心是不要遍历原始请求字节串。

内容的提问来源于stack exchange,提问作者Emm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 01:09:25