Scan iteration

Iterate through results from SCAN, HSCAN, etc.

Redis has a small family of related commands that retrieve keys and, in some cases, their associated values:

  • SCAN retrieves keys from the main Redis keyspace.
  • HSCAN retrieves keys and optionally, their values from a hash object.
  • SSCAN retrieves keys from a set object.
  • ZSCAN retrieves keys and their score values from a sorted set object.

These commands can potentially return large numbers of results, so Redis provides a paging mechanism to access the results in small, separate batches. With the basic commands, you must maintain a cursor value in your code to keep track of the current page. As a convenient alternative, redis-py also lets you access the results using an iterator. This handles the paging transparently, so you simply need to process the items it returns one-by-one in a for loop or pass the iterator object itself in place of a sequence.

Each of the commands has its own equivalent iterator. The following example shows how to use a SCAN iterator on the Redis keyspace. Note that, as with the SCAN command, the results are not sorted into any particular order, . Also, you can pass match, count, and _type parameters to scan_iter() to constrain the set of keys it returns (see the SCAN command page for examples).

import redis

r = redis.Redis(decode_responses=True)

r.set("key:1", "a")
r.set("key:2", "b")
r.set("key:3", "c")
r.set("key:4", "d")
r.set("key:5", "e")

for key in r.scan_iter():
    print(f"Key: {key}, value: {r.get(key)}")
# >>> Key: key:1, value: a
# >>> Key: key:4, value: d
# >>> Key: key:3, value: c
# >>> Key: key:2, value: b
# >>> Key: key:5, value: e

The iterators for the other commands are also named with _iter() after the name of the basic command (hscan_iter(), sscan_iter(), and zscan_iter()). They work in a similar way to scan_iter() except that you must pass a key to identify the object you want to scan. The example below shows how to iterate through the items in a sorted set using zscan_iter().

r.zadd("battles", mapping={
    "hastings": 1066,
    "agincourt": 1415,
    "trafalgar": 1805,
    "somme": 1916,
})

for item in r.zscan_iter("battles"):
    print(f"Key: {item[0]}, value: {int(item[1])}")
# >>> Key: hastings, value: 1066
# >>> Key: agincourt, value: 1415
# >>> Key: trafalgar, value: 1805
# >>> Key: somme, value: 1916

Note that in this case, the item returned by the iterator is a tuple with two elements for the key and score. By default, hscan_iter() also returns a 2-tuple for the key and value, but you can pass a value of True for the no_values parameter to retrieve just the keys:

r.hset("details", mapping={
    "name": "Mr Benn",
    "address": "52 Festive Road",
    "hobbies": "Cosplay"
})

for key in r.hscan_iter("details", no_values=True):
    print(f"Key: {key}, value: {r.hget("details", key)}")
# >>> Key: name, value: Mr Benn
# >>> Key: address, value: 52 Festive Road
# >>> Key: hobbies, value: Cosplay
RATE THIS PAGE
Back to top ↑