Redis 使用 Python ORM ROM 手动设置主键

Redis set primary key manually using the Python ORM ROM

我正在尝试使用 rom Python ORM 在 Redis 中存储对象。

我有以下型号:

import rom

class Repository(rom.Model):
    id = rom.PrimaryKey()
    topics = rom.Json()

我想创建一个可以手动设置主键的实例,例如:

repo = Repository()
repo.id = 1337
repo.topics = ["topic1", "topic2"]

然而,当我尝试这样做时,出现以下错误:

Traceback (most recent call last): [...] raise InvalidOperation("Cannot update primary key value") rom.exceptions.InvalidOperation: Cannot update primary key value

基本上,我希望能够设置主键的值,以便在数据库中的条目看起来像:

127.0.0.1:6379[1]> KEYS *
1) "Repository:243"
2) "Repository:1337"
3) "Repository:9001"

而不是:

127.0.0.1:6379[1]> KEYS *
1) "Repository:1"
2) "Repository:2"
3) "Repository:3"

是的,有一种方法,但不是您所发现的默认方法。只要您使用的是整数,您就可以使用一些魔法来实现它。

首先,这通常是不可能的,因为模型的元类强制执行主键,并强制在初始化时取消设置属性。但是,基于我保证不会更改(我也使用它)的内部和未记录的API,您可以:

def load_and_save_with_known_pk(model, data):
    """
    WARNING: will likely overwrite anything in Redis without a lock / check.
    WARNING: "data" may need to be encoded like how rom gets data out of
        Redis. It's probably something like: {"attr": json.dumps(<val>).encode(), ...}
    """
    # I am how rom loads models from Redis itself, wow!
    entity = model(_loading=True, **data)
    # this is how you make sure that the data is persisted
    entity.save(force=True)

如果你想绕过会话或其他东西,那里有几个内部挂钩,检查使用的内部参数并通过 __init__ 方法填充:https://github.com/josiahcarlson/rom/blob/master/rom/model.py#L247