Livid
406.45D
549.2D
V2EX  ›  Redis

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

  •  1
     
  •   Livid ·
    PRO
    · Jun 19, 2019 · 20545 views
    This topic created in 2704 days ago, the information mentioned may be changed or developed.

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

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

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