首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Redis

今天踩了一个 redis-py 的坑,分享一下

  •  1
     
  •   Livid · 126 天前 · 12749 次点击
    这是一个创建于 126 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Redis 的 Python 客户端的 zincrby 的参数顺序在 redis-py 3 里改了。

    在 redis-py 2 里是:

    def zincrby(self, name, value, amount=1):
    

    在 redis-py 3 里是:

    def zincrby(self, name, amount, value):
    

    具体的改动是这个 commit:

    https://github.com/andymccurdy/redis-py/commit/a750c7946d41862a38955c35b6928f098911c406

    本来觉得这种基础库上不太可能发生这种事情,直到今天在用 Docker 搭一个新开发环境的时候……

    如果要同时兼容两种情况的话,可以这样做:

    import redis
    
    print(redis.VERSION)
    

    redis.VERSION 里的第一个元素就是大版本号。

    37 回复  |  直到 2019-09-01 06:49:55 +08:00
        1
    enzo113   126 天前   ♥ 1
    这改动确实反人类。
    我想到了一个别的解决方法:可以显式的把参数写出来,如 amount=1, value="2", 调用的时候就能无视顺序了。
        2
    Abbeyok   126 天前 via Android
    这个是个坑,之前遇到过
        3
    chengxiao   126 天前
    今天我也发现一个 pymongo 的坑
    Mongodb 从 3.6 版本开始就支持字典 key 包含. $等特殊符号了
    但是在 pymongo 里还是会做拼写检查,需要到 site-package 里把 collection 把 check_key=True 改 False 即可
        4
    opengps   126 天前   ♥ 1
    这种改动还不如加个新方法
        5
    jamfer   126 天前
    这.... 还带这么玩儿的???
        6
    Valid   126 天前
    最骚的是 amount
        7
    scriptB0y   126 天前
    可以理解吧,可能一开始作者是想设置一个 default 的 increment=1,然后就将带默认值的参数放到最后面了。

    后来有人提出这跟 redis 原生的命令相反了 github.com/andymccurdy/redis-py/issues/571

    然后作者就改回去了。
        8
    cominghome   126 天前   ♥ 1
    一直是显示传参,但是这个改动确实坑
        9
    xiaolanger   126 天前
    上次用这个的时候,也是仔细看了看文档
        10
    iPhoneXI   126 天前   ♥ 1
    redis py setex 顺序也是坑,还是指定关键字完事
        11
    wsbnd9   126 天前   ♥ 1
    python3 StrictRedis zadd 坑


    import redis
    r = redis.Redis(...)
    if redis.VERSION[0] < 3:
    r.zadd('my-key', element1=score1)
    else:
    r.zadd('my-key', {element1: score1})



    这个也是坑
        12
    Yyyye   126 天前
    为什么不直接添加一个新方法呢!
        13
    mengyaoss77   126 天前 via Android
    感觉 redis 的有序集合操作语义很奇怪啊 member 在后 score 在前。。
        15
    Ehco1996   126 天前
    还有 exists 的返回值从 None 变为 0 了
        16
    Mithrandir   126 天前
    所以要读 changelog
        17
    raptor   126 天前
    @iPhoneXI 同被 setex 坑过
        18
    Mirage09   126 天前
    ....居然还能这么换顺序的
        19
    fireindark   125 天前
    pika 的 python2 和 python3 也有这个问题
        20
    coolzilj   125 天前
    大版本更新有 backwards incompatible changes 也很正常吧
        21
    bytelee   120 天前
    同碰到,当时以为自己傻逼了。。。。后来看了下文档,发现次序变了。然后就显示给参数了
        22
    ddup   120 天前
    这。。。还是喜欢强类型库,随便怎么重构也不担心,编译就报错了。
        23
    Takamine   120 天前
    如果用 IDE 的话在键入参数的时候应该是有参数提示的哇。
        24
    tiedan   120 天前
    哈哈哈,我踩过这个坑
        25
    hubqin   119 天前
    难怪我周末看 redis in action,有个例子运行老是出错,耗费了我好多时间。还有 zadd,redis-py3.0 版本下,第二个参数是字典类型,没想到 zincrby 也不用一样。这个改动估计是要跟随 redis 原生命令的参数顺序。
        26
    onlyice   119 天前
    虽然挺坑,但是人家文档也是描述了这个事情的: https://github.com/andymccurdy/redis-py/tree/3.2.1#zincrby
        27
    midtin   119 天前
    人家文档都写清楚了,升级大版本不看清文档怪谁呢。。
        28
    mooncakejs   119 天前
    py 这种坑太多了,上梁不正下梁歪。
        29
    sobigfish   119 天前
    正常增减应该是新建个方法 原来的设为弃用 Deprecated 吧
        30
    vast0906   119 天前
    yaml 3.6 和 5.1 load 差别貌似更大
        31
    itskingname   119 天前 via iPhone
    我录了一个视频,来说明这些改动: http://www.bilibili.com/video/av48634169
        32
    okoook   119 天前 via iPhone
    php 里面的参数是正常顺序,py 前一版都是颠倒的,重写很烦,这次升级结束,发现新版又正回来了,又又又得重写
        33
    cz5424   119 天前 via iPhone
    zadd 也是坑
        34
    icylogic   119 天前 via iPad
    强类型也不一定能解决啊,调换顺序的参数可能类型一样啊。这要覆盖很好的测试才有可能测出来。
    所以
    1. Named args
    2. Major Version 升级要慎重,至少不能连升级指南都不看,changelog 里的 breaking changes 都不看。按照 semantic version 的约定,Major 版本更改就是允许破坏性更新存在的。除了楼上提到的升级指南,不出意外地在 changelog 里找到了

    * 3.0.0
    BACKWARDS INCOMPATIBLE CHANGES
    ...
    * ZINCRBY arguments 'value' and 'amount' have swapped order to match the
    the Redis server. The new argument order is: keyname, amount, value.
    * MGET no longer raises an error if zero keys are passed in. Instead an
    empty list is returned.
    * MSET and MSETNX now require all keys/values to be specified in a single
    dictionary argument named mapping. This was changed to allow for future
    options to these commands in the future.
    * ZADD now requires all element names/scores be specified in a single
    dictionary argument named mapping. This was required to allow the NX,
    XX, CH and INCR options to be specified.
        35
    icylogic   119 天前 via iPad
    所以建议再看一遍这些 breaking changes,说不定又能发现隐藏的新坑。
        36
    Livid   V2EX Moderator   118 天前
    @icylogic requirements.txt 里几十个库,大家有什么好的方法来追踪最新的 breaking change 呢?
        37
    phy25   53 天前 via Android
    @Livid #36 requirements.txt 通常是用 pip freeze 固定版本的,如果版本有升级可以手动发现?
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3658 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 26ms · UTC 04:11 · PVG 12:11 · LAX 21:11 · JFK 00:11
    ♥ Do have faith in what you're doing.