用Python获取Redis数据库中的所有键

如果你知道JSON,Redis的设计系统会很熟悉。它使用key-value 结构和分布式及内存方法来实现一个有弹性的数据库。

哈希值、列表、集、排序集、字符串、JSON和流是Redis支持的众多数据结构之一。这个开源数据库支持不同的语言,包括Python,如果你要用它开发一个后台系统,一些模块和包会对此有所帮助。

你经常使用数据库进行的许多操作之一是检索数据,在像Redis 这样的数据库中,键是实现这种操作的重要条件。

本文将讨论如何获取Redis数据库中的所有键。

使用keys() 来获取Redis数据库中的所有键

为了使用redis ,我们需要安装它;你可以通过Redis的下载页面来了解如何安装。对于Linux和macOS用户来说,这是很容易的;然而,对于Windows用户来说,你可能需要使用Windows Subsystem for Linux(WSL2),你可以按照他们的说明视频指南。

假设你已经设置了你的Redis数据库,我们将安装redis 包,它提供对Redis数据库的客户端访问。为了安装它,我们将使用pip 命令。

pip install redis

输出:

Collecting redis
  Downloading redis-4.3.4-py3-none-any.whl (246 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 246.2/246.2 kB 794.4 kB/s eta 0:00:00
Collecting deprecated>=1.2.3
  Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB)
Collecting async-timeout>=4.0.2
  Downloading async_timeout-4.0.2-py3-none-any.whl (5.8 kB)
Collecting packaging>=20.4
  Downloading packaging-21.3-py3-none-any.whl (40 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40.8/40.8 kB 1.9 MB/s eta 0:00:00
Collecting wrapt<2,>=1.10
  Downloading wrapt-1.14.1-cp310-cp310-win_amd64.whl (35 kB)
Collecting pyparsing!=3.0.5,>=2.0.2
  Downloading pyparsing-3.0.9-py3-none-any.whl (98 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.3/98.3 kB 624.8 kB/s eta 0:00:00
Installing collected packages: wrapt, pyparsing, async-timeout, packaging, deprecated, redis
Successfully installed async-timeout-4.0.2 deprecated-1.2.13 packaging-21.3 pyparsing-3.0.9 redis-4.3.4 wrapt-1.14.1

因此,redis 包使用wrapt,pyparsing,async-timeout,packaging, 和已废弃的模块来驱动其模块。

为了利用redis 包,我们需要导入它。

import redis

继续讨论主要问题,我们可以使用redis 模块提供的keys() 方法来访问并获得所有的键入。

key() 方法从一个给定的Redis数据库中返回一个与参数中传递的模式相匹配的键的列表。如果没有传递参数,则有一个默认模式,即* ,这意味着所有的键。

为了显示该方法的工作情况,我们使用+Key 按钮或下面的代码,手动预填充了redis 数据库,其别名为Temp ,其中有一些键。

import redis
redisHost = 'localhost'
redisPort = 6379
redisDecodeRes = True
r = redis.StrictRedis(
            host=redisHost,
            port=redisPort,
            decode_responses=redisDecodeRes
        )
r.set("ConnectionPool", "Ox1212af34w3141")

上述代码的结果是,键ConnectionPool 被添加到Temp 数据库中,并有相应的值。

set() 方法将key-value 对应用到数据库中,而StrictRedis() 方法创建了一个 Redis 连接对象,使我们能够访问数据库。

为了通过图形用户界面显示数据库(别名为Temp )及其键,我们可以使用RedisInsight 应用程序,如图所示。

用Python获取Redis数据库中的所有键

为了测试key() 方法,总共有11个键被手动添加到数据库中。

现在,对于key() 方法,我们将不得不使用StrictRedis() 方法来创建一个Redis连接对象来访问这些键。host,port, 和decode_responses 参数被传递来定义连接的参数。

hostport 定义了主机名和端口号,而decode_responses 定义了所传递的数据被解码为我们可以轻松处理的 Python 字符串。然后keys() 方法访问所有可用的键,因为没有传递参数。

import redis
redisHost = 'localhost'
redisPort = 6379
redisDecodeRes = True
r = redis.StrictRedis(
    host=redisHost,
    port=redisPort,
    decode_responses=redisDecodeRes,
    db=0
    )
print(r.keys())

输出:

['bar-two', 'information', 'bar-one', 'details', 'foo', 'jinku', 'bar', 'User-One', 'delft', 'bar-three', 'ConnectionPool']

我们有一个Temp 数据库中所有键的列表,我们可以用它来工作。

如果我们有一个我们需要的键的模式,我们可以把它作为一个参数传递。让我们列出所有以bar 开始的键。

print(r.keys(pattern="bar*"))

输出:

['bar-two', 'bar-one', 'bar', 'bar-three']

使用scan_iter() 来获取Redis数据库中的所有密钥

对于一个大的数据库,scan_iter() 可以让我们在Python应用程序中更好地管理数据。另外,key() 方法会阻塞服务器并阻止其他使用操作,而使用scan_iter() ,其基于批次的操作允许其他使用操作。

尽管keys() 可能更快,但对于基于多请求的系统来说,它不是很好。

现在,让我们看看它的运行情况。

import redis
redisHost = 'localhost'
redisPort = 6379
redisDecodeRes = True
try:
    r = redis.StrictRedis(
        host=redisHost,
        port=redisPort,
        decode_responses=redisDecodeRes,
        db=0
    )
    for key in r.scan_iter(match="bar*"):
        print(key)
except Exception as e:
    print(e)

输出:

bar-three
bar-one
bar-two
bar

当我们试图使用数据库时,使用try/except ,有助于处理连接问题。在使用StrictRedis() 进行连接后,我们使用match 参数来定义我们正在寻找的密钥模式,并在结果中进行循环以给出密钥。

使用zip_longest 来获取Redis数据库中的所有密钥

正如我们所说,对于有很多键的大型数据库,scan_iter() 方法更好,但我们可以进一步改进,以指定数量的批次检索键,以更好地管理结果。

为了创建batch ,我们需要itertools 模块,该模块提供不同的迭代器(或方法),可用于不同的情况。在itertools 模块中,我们有zip_longest 方法,它返回一个zip_longest 对象,其.next() 方法返回一个元组,并从传递给它的可迭代的元素中聚合。

我们可以使用zip_longest() 方法来制作一个函数,根据传递的参数创建一批指定数量的键。例如,我们创建一个2的批处理,这可以用于许多情况。

import redis
from itertools import zip_longest
redisHost = 'localhost'
redisPort = 6379
redisDecodeRes = True
try:
    r = redis.StrictRedis(
        host=redisHost,
        port=redisPort,
        decode_responses=redisDecodeRes,
        db=0
    )
    def batch(iterable, num):
        initIter = [iter(iterable)] * num
        return zip_longest(*initIter)
    for keyBatch in batch(r.scan_iter('bar*'), 2):
        print(keyBatch)
except Exception as e:
    print(e)

输出:

('bar-three', 'bar-one')
('bar-two', 'bar')