MENU

Python与redis数据交互的坑

前言

最近遇到一个将线上的redis数据同步到本地开发环境,想着直接用Python小脚本的方式直接同步就好了。线上是zadd有序集合的数据,习惯性的将平时在shell交互环境方式写。(如下)

# shell交互方式zadd数据
ZADD key score member

# 本次在Python脚本方式写的(错误情况)
online = redis.Redis(host="ip", port="端口")
local = redis.Redis(host="ip", port="端口")
local_pip = local.pipeline()
local_pip.zadd(key, score, member)  // 错误示范

导致AttributeError: 'float' object has no attribute 'items'错误。

问题发现以及解决

  • 问题追查
    一开始还以为是浮点型不支持导致后将其转成int型,发现还是报相同的错误。后面网上找到发现上面这中写法旧版是支持的,目前新版不在支持。

    # 该方式旧版支持
    zadd: redis.zadd(REDIS_KEY, score, member)
    
    # 新版
    # SORTED SET COMMANDS
    def zadd(self, name, mapping, nx=False, xx=False, ch=False, incr=False):
    """
    Set any number of element-name, score pairs to the key ``name``. Pairs
    are specified as a dict of element-names keys to score values.
    
    ``nx`` forces ZADD to only create new elements and not to update
    scores for elements that already exist.
    
    ``xx`` forces ZADD to only update scores of elements that already
    exist. New elements will not be added.
    
    ``ch`` modifies the return value to be the numbers of elements changed.
    Changed elements include new elements that were added and elements
    whose scores changed.
    
    ``incr`` modifies ZADD to behave like ZINCRBY. In this mode only a
    single element/score pair can be specified and the score is the amount
    the existing score will be incremented by. When using this mode the
    return value of ZADD will be the new score of the element.
    
    The return value of ZADD varies based on the mode specified. With no
    options, ZADD returns the number of new elements added to the sorted
    set.
    """
    if not mapping:
        raise DataError("ZADD requires at least one element/score pair")
    if nx and xx:
        raise DataError("ZADD allows either 'nx' or 'xx', not both")
    if incr and len(mapping) != 1:
        raise DataError("ZADD option 'incr' only works when passing a "
                        "single element/score pair")
    pieces = []
    options = {}
    if nx:
        pieces.append(b'NX')
    if xx:
        pieces.append(b'XX')
    if ch:
        pieces.append(b'CH')
    if incr:
        pieces.append(b'INCR')
        options['as_score'] = True
    for pair in iteritems(mapping):
        pieces.append(pair[1])
        pieces.append(pair[0])
    return self.execute_command('ZADD', name, *pieces, **options)
    

    对于新版第二个参数是一个mapping,因此需要将score转成一个mapping后在zadd。

  • 解决

    # 正确的示例
     redis.zadd(REDIS_KEY, {member:score})
    
标签: Redis, Python
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码