Skip to main content

一种从 Redis 等键值数据库获取和存储数据的简单方法。

项目描述

数据库传输

PyPI 版本

使用 Redis 等键值数据库操作数据的简单方法。
它旨在支持多种数据库,但目前支持 Redis 和 yaml 文件。

安装

pip install DB-Transfer

设计

每个数据库都有一个适配器类。
在使用特定的adapter_name实例化Python Transfer之后,我们可以
像字典一样操作键值数据库中的数据:`transfer[key] = value`

钥匙

键是使用前缀、命名空间和项目创建的。
示例:data:USERS:arrrlo:full_name
(data 是前缀,USERS 是命名空间,arrrlo:full_name 是 item)

Redis 适配器:

使用环境变量连接到 Redis

在 docker 容器中使用时非常方便。

from db_transfer import Transfer, sent_env

os.environ['REDIS_HOST'] = 'localhost'
os.environ['REDIS_PORT'] = '6379'
os.environ['REDIS_DB'] = '0'

@sent_env('redis', 'HOST', 'REDIS_HOST')
@sent_env('redis', 'PORT', 'REDIS_PORT')
@sent_env('redis', 'DB', 'REDIS_DB')
class RedisTransfer(Transfer):

    def __init__(self, prefix=None, namespace=None):
        super().__init__(prefix=str(prefix), namespace=namespace, adapter_name='redis')

存储数据

rt = RedisTransfer()
rt['my_key'] = 'some_string' # redis: "SET" "data:my_key" "some_string"

rt = RedisTransfer(namespace='my_namespace')
rt['my_key'] = 'some_string' # redis: "SET" "data:my_namespace:my_key" "some_string"

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace')
rt['my_key'] = 'some_string' # redis: "SET" "my_prefix:my_namespace:my_key" "some_string"

使用类参数连接到 Redis

class RedisTransfer(Transfer):

    def __init__(self, prefix, namespace, host, port, db):
        super().__init__(prefix=str(prefix), namespace=namespace, adapter_name='redis')

        self.set_env('HOST', host)
        self.set_env('PORT', port)
        self.set_env('DB', db)

存储数据

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)

rt['my_key'] = 'some_string' # redis: "SET" "my_prefix:my_name_space:my_key" "some_string"

获取数据

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)

my_var = rt['my_key'] # redis: "GET" "my_prefix:my_namespace:my_key"

删除数据

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)

del rt['my_key'] # redis: "DEL" "my_prefix:my_namespace:my_key"

其他数据类型

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)

rt['my_key_1'] = [1,2,3,4] # redis: "RPUSH" "my_prefix:my_namespace:my_key_1" "1" "2" "3" "4"
rt['my_key_2'] = {'foo', 'bar'} # redis: "SADD" "my_prefix:my_namespace:my_key_2" "foo" "bar"
rt['my_key_3'] = {'foo': 'bar'} # redis: "HMSET" "my_prefix:my_namespace:my_key_3" "foo" "bar"

my_var_1 = list(rt['my_key_1']) # redis: "LRANGE" "my_prefix:my_namespace:my_key_1" "0" "-1"
my_var_2 = set(rt['my_key_2']) # redis: "SMEMBERS" "my_prefix:my_namespace:my_key_2"
my_var_3 = dict(rt['my_key_2']) # redis: "HGETALL" "my_prefix:my_namespace:my_key_3"

Redis 哈希数据类型

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)

rt['my_key'] = {'foo': 'bar'} # redis: "HMSET" "my_prefix:my_namespace:my_key" "foo" "bar"

my_var = dict(rt['my_key']) # redis: "HGETALL" "my_prefix:my_namespace:my_key"
my_var = rt['my_key']['foo'] # redis: "HGET" "my_prefix:my_namespace:my_key" "foo"

rt['my_key']['boo'] = 'doo' # redis: "HSET" "my_prefix:my_namespace:my_key" "boo" "bar"

使用上下文管理器执行多个命令(仅用于设置和删除)

with RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0) as rt:
    rt['my_key_1'] = 'some_string'
    rt['my_key_2'] = [1,2,3,4]
    rt['my_key_3'] = {'foo': 'bar'}

# redis:
#
# "MULTI"
# "SET" "my_prefix:my_namespace:my_key_1" "some_string"
# "RPUSH" "my_prefix:my_namespace:my_key_2" "1" "2" "3" "4"
# "HMSET" "my_prefix:my_namespace:my_key_3" "foo" "bar"
# "EXEC"

使用迭代器

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)

for key, value in iter(rt):
    # yields key and value of every key starting with my_prefix:my_namespace:


rt['my_key'] = {...} # saving a hash data (dict)

for key, value in iter(rt['my_key']):
    # yields key and value for every HGET in my_prefix:my_namespace:my_key

钥匙

Redis 中的每个键都存储在同一个 Redis 中的集合中。
例子:

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)

rt['key_1'] = 'value'
rt['key_2:key3'] = 'value'
rt['key_2:key4'] = 'value'
rt['key_2:key_5:key_6'] = 'value'
rt['key_2:key_5:key_7'] = 'value'
rt['key_2:key_5:key_8'] = 'value'

因此,键是“key_1”、“key_2:key3”、“key_2:key4”、“key_2:key5:key_6”、“key_2:key5:key_7”、“key_2:key5:key_8”。
它们不存储在一个集合中,但不同的密钥存储在不同的集合中:
'my_prefix:my_namespace': set({'key_1', 'key_2:keys'})
'my_prefix:my_namespace:key_2': set({'key_3 ', 'key_4', 'key_5:keys'})
'my_prefix:my_namespace:key_2:key_5': set({'key_6', 'key_7', 'key_8'})

这是通过这种方式完成的,因此您可以通过任何级别的键轻松地递归访问数据:

rt.keys()
# > ['key_1', 'key_2:key3', 'key_2:key4', 'key_2:key_5:key_6', 'key_2:key_5:key_7', 'key_2:key_5:key_8']

rt['key_2'].keys()
# > ['key_3', 'key_4', 'key_5:key_6', 'key_5:key_7', 'key_5:key_8']

rt['key_2:key_5'].keys()
# > ['key_6', 'key_7', 'key_8']

现实生活中的例子

将所有数据从一个 Redis 数据库传输到另一个:

rt_1 = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)
rt_2 = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='some_host', port=6379, db=0)

for key in rt_1.keys():
    rt_2[key] = rt_1[key]

或者如果你想在一批中插入数据(读取一个接一个):

with rt_2:
    for key in rt_1.keys():
        rt_2[key] = rt_1[key]

将数据从一个用户传输到另一个用户:

rt_1 = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)

for key in rt_1['arrrlo'].keys():
    rt_1['edi:' + key] = rt_1['arrrlo:' + key]

从数据库中删除用户:

rt_1 = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)

with rt_1:
    for key in rt_1['arrrlo'].keys():
        del rt_1['arrrlo:' + key]

Yaml 文件适配器:

最初,来自 yaml 文件的数据从文件传输到内存。
从那里每次读取、写入或删除都会运行,直到
调用 sync() 方法。然后将内存中的数据传输到 yaml 文件中。
可以使用上下文管理器或手动调用 sync() 方法。

使用环境变量定义 yaml 文件的路径

在 docker 容器中使用时非常方便。

from db_transfer import Transfer, sent_env

os.environ['YAML_FILE_PATH'] = '/path/to/yaml/file.yaml'

@sent_env('yaml', 'FILE_LOCAL', 'YAML_FILE_PATH')
class YamlFileTransfer(Transfer):

    def __init__(self, prefix=None, namespace=None):
        super().__init__(prefix=str(prefix), namespace=namespace, adapter_name='yaml')

使用类参数定义 yaml 文件的路径

class YamlFileTransfer(Transfer):

    def __init__(self, prefix, namespace, yaml_file_path):
        super().__init__(prefix=str(prefix), namespace=namespace, adapter_name='yaml')

        self.set_env('FILE_LOCAL', yaml_file_path)

写入和删除数据

可以使用上下文管理器或 sync() 方法写入数据。

yt = YamlFileTransfer(prefix='my_prefix', namespace='my_namespace', yaml_file_path='/path/')

with yt:
    yt['my_key_1'] = 'some_string'

yt['my_key_2'] = 'some_string'
yt.sync()

with yt:
    del yt['my_key_1']

del yt['my_key_2']
yt.sync()

现实生活中的例子

将用户数据从 Redis 备份到 yaml 文件:

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)
yt = YamlFileTransfer(prefix='my_prefix', namespace='my_namespace', yaml_file_path='/path/')

for key in rt['arrrlo'].keys():
    yt['arrrlo:' + key] = rt['arrrlo:' + key]

# or (depends on how you use prefix and namespace):

rt = RedisTransfer(prefix='users', namespace='arrrlo', host='localhost', port=6379, db=0)
yt = YamlFileTransfer(prefix='users', namespace='arrrlo', yaml_file_path='/path/')

for key in rt.keys():
    yt[key] = rt[key]

# or:

rt = RedisTransfer(prefix='my_prefix:my_namespace', namespace='arrrlo', host='localhost', port=6379, db=0)
yt = YamlFileTransfer(prefix='my_prefix:my_namespace', namespace='arrrlo', yaml_file_path='/path/')

for key in rt.keys():
    yt[key] = rt[key]

# or:

rt = RedisTransfer(prefix='my_prefix', namespace='my_namespace', host='localhost', port=6379, db=0)
yt = YamlFileTransfer(prefix='my_prefix:my_namespace', namespace='arrrlo', yaml_file_path='/path/')

for key in rt.keys():
    yt[key] = rt['arrrlo:' + key]

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布