diff --git a/.github/wordlist.txt b/.github/wordlist.txt index 43b75871..bcd53463 100644 --- a/.github/wordlist.txt +++ b/.github/wordlist.txt @@ -121,3 +121,7 @@ UnicodeDecodeError VectorQuery VectorRangeQuery embeddings +UUID +lexicographically +Lexicographically +backport diff --git a/docs/models.md b/docs/models.md index 583b7abf..78c76e6b 100644 --- a/docs/models.md +++ b/docs/models.md @@ -127,6 +127,76 @@ Here is a table of the settings available in the Meta object and what they contr | index_name | The RediSearch index name to use for this model. Only used if the model is indexed (`index=True` on the model class). | "{global_key_prefix}:{model_key_prefix}:index" | | embedded | Whether or not this model is "embedded." Embedded models are not included in migrations that create and destroy indexes. Instead, their indexed fields are included in the index for the parent model. **Note**: Only `JsonModel` can have embedded models. | False | | encoding | The default encoding to use for strings. This encoding is given to redis-py at the connection level. In both cases, Redis OM will decode binary strings from Redis using your chosen encoding. | "utf-8" | + +### Custom Primary Key Creators + +By default, Redis OM uses ULID (Universally Unique Lexicographically Sortable Identifier) for primary keys. ULIDs are 128-bit identifiers that are lexicographically sortable and contain a timestamp component. + +You can customize how primary keys are generated by providing a custom `primary_key_creator_cls` in the Meta object. This is useful when you need a specific ID format, such as UUID v7. + +#### Using UUID v7 + +UUID v7 is a time-ordered UUID that provides similar benefits to ULID with better compatibility with existing UUID infrastructure. Here's how to use it: + +```python +import uuid +from redis_om import HashModel + +class UUIDv7PrimaryKey: + @staticmethod + def create_pk(*args, **kwargs) -> str: + return str(uuid.uuid7()) + +class MyModel(HashModel): + name: str + + class Meta: + primary_key_creator_cls = UUIDv7PrimaryKey +``` + +**Note:** `uuid.uuid7()` requires Python 3.11+ or a backport library like `uuid6`. + +#### Custom Primary Key Protocol + +Your custom primary key creator class must implement a `create_pk` static method that returns a string: + +```python +class CustomPrimaryKey: + @staticmethod + def create_pk(*args, **kwargs) -> str: + # Return your custom primary key as a string + return generate_my_custom_id() +``` + +#### Sharing Primary Key Creators + +You can use an abstract base model to share a custom primary key creator across multiple models: + +```python +from abc import ABC +import uuid +from redis_om import HashModel + +class UUIDv7PrimaryKey: + @staticmethod + def create_pk(*args, **kwargs) -> str: + return str(uuid.uuid7()) + +class BaseModel(HashModel, ABC): + class Meta: + primary_key_creator_cls = UUIDv7PrimaryKey + +class Customer(BaseModel): + name: str + email: str + +class Order(BaseModel): + product: str + quantity: int + +# Both Customer and Order will use UUID v7 for primary keys +``` + ## Configuring Pydantic Every Redis OM model is also a Pydantic model, so in addition to configuring Redis OM behavior with the Meta object, you can control Pydantic configuration via the Config object within a model class.