Redis bindings is an attempt to bring Redis types into Python as native ones. It is based on redis-py and has the following types implemented so far:
Moreover, it provides some abstract classes as Redis descriptors:
- IRedisField
- IRedisListField
- IRedisDictField
The classes are abstract because it requires user to override get_key_name
method to define key name for Redis. Here is an example of how it can be
implemented (can be found in example.py).
"""An example of the Redis descriptors usage."""
from redis import Redis
from redistypes import IRedisField, IRedisListField
r_connection = Redis()
class RedisField(IRedisField):
"""IRedisField implementation."""
def __init__(self, pickling=True):
"""Set ``r_connection`` as the Redis connection pool by default."""
super().__init__(
redis_connection=r_connection,
pickling=pickling,
)
def get_key_name(self, instance):
"""
Return Redis key name of the attribute.
It enforces instance using this descriptor to have the ``pk`` attribute.
"""
return ':'.join([
instance.__class__.__name__, str(instance.pk), self.name,
])
class RedisListField(RedisField, IRedisListField):
"""IRedisListField implementation."""
class Student(object):
"""Casual model of student."""
name = RedisField()
subjects = RedisListField()
def __init__(self, pk, name=None, subjects=None):
"""Student instance has to be initialized with a primary key ``pk``."""
self.pk = pk
if name:
self.name = name
if subjects:
self.subjects = subjects
The defined above Student
model has the following behaviour:
>>> from example import Student
>>> student = Student(pk=1, name='John Galt', subjects=['math', 'physics'])
>>> student.name
John Galt
>>> student.subjects
RedisList: ['math', 'physics']
>>> student.subjects.append('p.e.')
>>> student.subjects
RedisList: ['math', 'physics', 'p.e.']
>>> student.subjects[-1] = 'art'
>>> student.subjects
RedisList: ['math', 'physics', 'art']
Let's check what keys we've got in Redis:
>>> from redis import Redis
>>> r = Redis()
>>> r.keys()
[b'Student:1:name', b'Student:1:subjects']
As you saw above, we are able to change items of the RedisList, e.g. replace one subject with another by index. But what if we set list value to the regular field? Let's replace name of the student with list consisting of the first name and the last name.
>>> student.name = ['John', 'Galt']
>>> student.name
['John', 'Galt']
>>> student.name[-1] = 'Smith'
>>> student.name
['John', 'Galt']
In that way, we changed the name value from string to list of two items, but since
name
is a simple RedisField keeping all value as string in Redis, we are not
able to modify stored items themselves.
All values stored inside the Redis data structures are immutable!
As the example above shows, index lookup from the list stored as string in redis will
return a copy of the item.