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

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

  •  1
     
  •   Livid · 2019-06-19 16:59:36 +08:00 · 19013 次点击
    这是一个创建于 1994 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    然后作者就改回去了。
    cominghome
        8
    cominghome  
       2019-06-19 18:37:20 +08:00   ❤️ 1
    一直是显示传参,但是这个改动确实坑
    xiaolanger
        9
    xiaolanger  
       2019-06-19 19:26:59 +08:00
    上次用这个的时候,也是仔细看了看文档
    iPhoneXI
        10
    iPhoneXI  
       2019-06-19 19:43:19 +08:00   ❤️ 1
    redis py setex 顺序也是坑,还是指定关键字完事
    wsbnd9
        11
    wsbnd9  
       2019-06-19 20:20:00 +08:00   ❤️ 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})



    这个也是坑
    Yyyye
        12
    Yyyye  
       2019-06-19 20:38:43 +08:00
    为什么不直接添加一个新方法呢!
    mengyaoss77
        13
    mengyaoss77  
       2019-06-19 20:39:50 +08:00 via Android
    感觉 redis 的有序集合操作语义很奇怪啊 member 在后 score 在前。。
    Ehco1996
        15
    Ehco1996  
       2019-06-20 07:31:06 +08:00
    还有 exists 的返回值从 None 变为 0 了
    Mithrandir
        16
    Mithrandir  
       2019-06-20 09:54:45 +08:00
    所以要读 changelog
    raptor
        17
    raptor  
       2019-06-20 10:14:26 +08:00
    @iPhoneXI 同被 setex 坑过
    Mirage09
        18
    Mirage09  
       2019-06-20 10:16:42 +08:00
    ....居然还能这么换顺序的
    fireindark
        19
    fireindark  
       2019-06-20 17:14:40 +08:00
    pika 的 python2 和 python3 也有这个问题
    coolzilj
        20
    coolzilj  
       2019-06-20 17:54:13 +08:00
    大版本更新有 backwards incompatible changes 也很正常吧
    bytelee
        21
    bytelee  
       2019-06-26 09:23:48 +08:00
    同碰到,当时以为自己傻逼了。。。。后来看了下文档,发现次序变了。然后就显示给参数了
    ddup
        22
    ddup  
       2019-06-26 09:30:03 +08:00
    这。。。还是喜欢强类型库,随便怎么重构也不担心,编译就报错了。
    Takamine
        23
    Takamine  
       2019-06-26 11:51:37 +08:00
    如果用 IDE 的话在键入参数的时候应该是有参数提示的哇。
    tiedan
        24
    tiedan  
       2019-06-26 12:06:52 +08:00
    哈哈哈,我踩过这个坑
    hubqin
        25
    hubqin  
       2019-06-26 12:16:48 +08:00
    难怪我周末看 redis in action,有个例子运行老是出错,耗费了我好多时间。还有 zadd,redis-py3.0 版本下,第二个参数是字典类型,没想到 zincrby 也不用一样。这个改动估计是要跟随 redis 原生命令的参数顺序。
    onlyice
        26
    onlyice  
       2019-06-26 15:05:59 +08:00
    虽然挺坑,但是人家文档也是描述了这个事情的: https://github.com/andymccurdy/redis-py/tree/3.2.1#zincrby
    midtin
        27
    midtin  
       2019-06-26 18:36:10 +08:00
    人家文档都写清楚了,升级大版本不看清文档怪谁呢。。
    mooncakejs
        28
    mooncakejs  
       2019-06-26 18:43:35 +08:00
    py 这种坑太多了,上梁不正下梁歪。
    sobigfish
        29
    sobigfish  
       2019-06-26 18:51:04 +08:00
    正常增减应该是新建个方法 原来的设为弃用 Deprecated 吧
    vast0906
        30
    vast0906  
       2019-06-26 18:57:35 +08:00
    yaml 3.6 和 5.1 load 差别貌似更大
    itskingname
        31
    itskingname  
       2019-06-26 20:00:10 +08:00 via iPhone
    我录了一个视频,来说明这些改动: http://www.bilibili.com/video/av48634169
    okoook
        32
    okoook  
       2019-06-26 20:12:00 +08:00 via iPhone
    php 里面的参数是正常顺序,py 前一版都是颠倒的,重写很烦,这次升级结束,发现新版又正回来了,又又又得重写
    cz5424
        33
    cz5424  
       2019-06-26 23:07:23 +08:00 via iPhone
    zadd 也是坑
    icylogic
        34
    icylogic  
       2019-06-27 08:23:50 +08:00 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.
    icylogic
        35
    icylogic  
       2019-06-27 08:26:32 +08:00 via iPad
    所以建议再看一遍这些 breaking changes,说不定又能发现隐藏的新坑。
    Livid
        36
    Livid  
    MOD
    OP
       2019-06-27 13:05:57 +08:00
    @icylogic requirements.txt 里几十个库,大家有什么好的方法来追踪最新的 breaking change 呢?
    phy25
        37
    phy25  
       2019-09-01 06:49:55 +08:00 via Android
    @Livid #36 requirements.txt 通常是用 pip freeze 固定版本的,如果版本有升级可以手动发现?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1360 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 17:48 · PVG 01:48 · LAX 09:48 · JFK 12:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.