提交 20639c33 编写于 作者: A Andy McCurdy

redis-py 3.0.0

上级 69eb38ff
* UNRELEASED
* Removed support for EOL Python 2.6 and 3.3.
* 3.0.0
BACKWARDS INCOMPATIBLE CHANGES
* When using a Lock as a context manager and the lock fails to be acquired
a LockError is now raised. This prevents the code block inside the
context manager from being executed if the lock could not be acquired.
* Renamed LuaLock to Lock.
* Removed the pipeline based Lock implementation in favor of the LuaLock
implementation.
* Only bytes, strings and numbers (ints, longs and floats) are acceptable
for keys and values. Previously redis-py attempted to cast other types
to str() and store the result. This caused must confusion and frustration
when passing boolean values (cast to 'True' and 'False') or None values
(cast to 'None'). It is now the user's responsibility to cast all
key names and values to bytes, strings or numbers before passing the
value to redis-py.
* The StrictRedis class has been renamed to Redis. StrictRedis will
continue to exist as an alias of Redis for the forseeable future.
* The legacy Redis client class has been removed. It caused much confusion
to users.
* 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.
* Removed support for EOL Python 2.6 and 3.3. Thanks jdufresne
OTHER CHANGES
* Added missing DECRBY command. Thanks derek-dchu
* CLUSTER INFO and CLUSTER NODES respones are now properly decoded to
strings.
* Added a 'locked()' method to Lock objects. This method returns True
if the lock has been acquired and owned by the current process,
otherwise False.
* EXISTS now supports multiple keys. It's return value is now the number
of keys in the list that exist.
* Ensure all commands can accept key names as bytes. This fixes issues
with BLPOP, BRPOP and SORT.
* All errors resulting from bad user input are raised as DataError
exceptions. DataError is a subclass of RedisError so this should be
transparent to anyone previously catching these.
* Added support for NX, XX, CH and INCR options to ZADD
* Added support for the MIGRATE command
* Added support for the MEMORY USAGE and MEMORY PURGE commands. Thanks
Itamar Haber
* Added support for the 'asynchronous' argument to FLUSHDB and FLUSHALL
commands. Thanks Itamar Haber
* Added support for the BITFIELD command. Thanks Charles Leifer and
Itamar Haber
* Improved performance on pipeline requests with large chunks of data.
Thanks tzickel
* Fixed test suite to not fail if another client is connected to the
server the tests are running against.
* Added support for SWAPDB. Thanks Itamar Haber
* Added support for all STREAM commands. Thanks Roey Prat and Itamar Haber
* SHUTDOWN now accepts the 'save' and 'nosave' arguments. Thanks
dwilliams-kenzan
* Added support for ZPOPMAX, ZPOPMIN, BZPOPMAX, BZPOPMIN. Thanks
Itamar Haber
* Added support for the 'type' argument in CLIENT LIST. Thanks Roey Prat
* Added support for CLIENT PAUSE. Thanks Roey Prat
* Added support for CLIENT ID and CLIENT UNBLOCK. Thanks Itamar Haber
* GEODIST now returns a None value when referencing a place that does
not exist. Thanks qingping209
* Added a ping() method to pubsub objects. Thanks krishan-carbon
* Fixed a bug with keys in the INFO dict that contained ':' symbols.
Thanks mzalimeni
* ssl_cert_reqs now has a default value of 'required' by default. This
should make connecting to a remote Redis server over SSL more secure.
Thanks u2mejc
* Fixed the select system call retry compatibility with Python 2.x.
Thanks lddubeau
* max_connections is now a valid querystring argument for creating
connection pools from URLs. Thanks mmaslowskicc
* Added the UNLINK command. Thanks yozel
* Added socket_type option to Connection for configurability.
Thanks garlicnation
* Lock.do_acquire now atomically sets acquires the lock and sets the
expire value via set(nx=True, px=timeout). Thanks 23doors
* Added 'count' argument to SPOP. Thanks AlirezaSadeghi
* Fixed an issue parsing client_list respones that contained an '='.
Thanks swilly22
* 2.10.6
* Various performance improvements. Thanks cjsimpson
* Fixed a bug with SRANDMEMBER where the behavior for `number=0` did
......
......@@ -57,19 +57,146 @@ specify `decode_responses=True` to `Redis.__init__`. In this case, any
Redis command that returns a string type will be decoded with the `encoding`
specified.
Upgrading from redis-py 2.X to 3.0
----------------------------------
redis-py 3.0 introduces many new features but required a number of backwards
incompatible changes to be made in the process. This section attempts to
provide an upgrade path for users migrating from 2.X to 3.0.
Python Version Support
^^^^^^^^^^^^^^^^^^^^^^
redis-py 3.0 now supports Python 2.7 and Python 3.4+. Python 2.6 and 3.3
support has been dropped.
Client Classes: Redis and StrictRedis
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
redis-py 3.0 drops support for the legacy "Redis" client class. "StrictRedis"
has been renamed to "Redis" and an alias named "StrictRedis" is provided so
that users previously using "StrictRedis" can continue to run unchanged.
The 2.X "Redis" class provided alternative implementations of a few commands.
This confused users (rightfully so) and caused a number of support issues. To
make things easier going forward, it was decided to drop support for these
alternate implementations and instead focus on a single client class.
2.X users that are already using StrictRedis don't have to change the class
name. StrictRedis will continue to work for the forseeable future.
2.X users that are using the Redis class will have to make changes if they
use any of the following commands:
* SETEX: The argument order has changed. The new order is (name, time, value).
* LREM: The argument order has changed. The new order is (name, num, value).
* TTL and PTTL: The return value is now always an int and matches the
official Redis command (>0 indicates the timeout, -1 indicates that the key
exists but that it has no expire time set, -2 indicates that the key does
not exist)
MSET, MSETNX and ZADD
^^^^^^^^^^^^^^^^^^^^^
These commands all accept a mapping of key/value pairs. In redis-py 2.X
this mapping could be specified as *args or as **kwargs. Both of these styles
caused issues when Redis introduced optional flags to ZADD. Relying on *args
caused issues with the optional argument order, especially in Python 2.7.
Relying on **kwargs caused potential collision issues of user keys with the
argument names in the method signature.
To resolve this, redis-py 3.0 has changed these three commands to all accept
a single positional argument named mapping that is expected to be a dict.
MSET, MSETNX and ZADD now look like:
.. code-block:: pycon
def mset(self, mapping):
def msetnx(self, mapping):
def zadd(self, name, mapping, nx=False, xx=False, ch=False, incr=False):
All 2.X users that use these commands must modify their code to supply
keys and values as a dict to these commands.
ZINCRBY
^^^^^^^
redis-py 2.X accidentily modified the argument order of ZINCRBY, swapping the
order of value and amount. ZINCRBY now looks like:
.. code-block:: pycon
def zincrby(self, name, amount, value):
All 2.X users that rely on ZINCRBY must swap the order of amount and value
for the command to continue to work as intended.
Encoding of User Input
^^^^^^^^^^^^^^^^^^^^^^
redis-py 3.0 only accepts user data as bytes, strings or numbers (ints, longs
and floats). Attempting to specify a key or a value as any other type will
raise a DataError exception.
redis-py 2.X attempted to coerce any type of input into a string. While
occasionally convenient, this caused all sorts of hidden errors when users
passed boolean values (which were coerced to 'True' or 'False'), a None
value (which was coerced to 'None') or other values, such as user defined
types.
All 2.X users should make sure that the keys and values they pass into
redis-py are either bytes, strings or numbers.
Locks
^^^^^
redis-py 3.0 drops support for the pipeline-based Lock and now only supports
the Lua-based lock. In doing so, LuaLock has been renamed to Lock. This also
means that redis-py Lock objects require Redis server 2.6 or greater.
2.X users that were explicitly referring to "LuaLock" will have to now refer
to "Lock" instead.
Locks as Context Managers
^^^^^^^^^^^^^^^^^^^^^^^^^
redis-py 3.0 now raises a LockError when using a lock as a context manager and
the lock cannot be acquired within the specified timeout. This is more of a
bug fix than a backwards incompatible change. However, given an error is now
raised where none was before, this might alarm some users.
2.X users should make sure they're wrapping their lock code in a try/catch
like this:
.. code-block:: pycon
try:
with r.lock('my-lock-key', blocking_timeout=5) as lock:
# code you want executed only after the lock has been acquired
except LockError:
# the lock wasn't acquired
API Reference
-------------
The `official Redis command documentation <https://redis.io/commands>`_ does a
great job of explaining each command in detail. redis-py exposes two client
classes that implement these commands. The Redis class attempts to adhere
great job of explaining each command in detail. redis-py attempts to adhere
to the official command syntax. There are a few exceptions:
* **SELECT**: Not implemented. See the explanation in the Thread Safety section
below.
* **DEL**: 'del' is a reserved keyword in the Python syntax. Therefore redis-py
uses 'delete' instead.
* **CONFIG GET|SET**: These are implemented separately as config_get or config_set.
* **MULTI/EXEC**: These are implemented as part of the Pipeline class. The
pipeline is wrapped with the MULTI and EXEC statements by default when it
is executed, which can be disabled by specifying transaction=False.
......@@ -88,18 +215,6 @@ to the official command syntax. There are a few exceptions:
to keep track of the cursor while iterating. Use the
scan_iter/sscan_iter/hscan_iter/zscan_iter methods for this behavior.
In addition to the changes above, the Redis class, a subclass of Redis,
overrides several other commands to provide backwards compatibility with older
versions of redis-py:
* **LREM**: Order of 'num' and 'value' arguments reversed such that 'num' can
provide a default value of zero.
* **ZADD**: Redis specifies the 'score' argument before 'value'. These were swapped
accidentally when being implemented and not discovered until after people
were already using it. The Redis class expects \*args in the form of:
`name1, score1, name2, score2, ...`
* **SETEX**: Order of 'time' and 'value' arguments reversed.
More Detail
-----------
......
......@@ -22,7 +22,7 @@ from redis.exceptions import (
)
__version__ = '2.10.6'
__version__ = '3.0.0'
VERSION = tuple(map(int, __version__.split('.')))
__all__ = [
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册