Skip to content

Commit b20e887

Browse files
authored
Make RedisModel compatible with Pydantic 2.x (#626)
* Make RedisModel compatible with Pydantic 2.x * Use direct import of ConfigDict instead of conditionally exporting it from _compat * Refactor to use PYDANTIC_V2 from _compat
1 parent dda2897 commit b20e887

File tree

5 files changed

+43
-22
lines changed

5 files changed

+43
-22
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ sync: $(INSTALL_STAMP)
5353
lint: $(INSTALL_STAMP) dist
5454
$(POETRY) run isort --profile=black --lines-after-imports=2 ./tests/ $(NAME) $(SYNC_NAME)
5555
$(POETRY) run black ./tests/ $(NAME)
56-
$(POETRY) run flake8 --ignore=W503,E501,F401,E731,E712 ./tests/ $(NAME) $(SYNC_NAME)
56+
$(POETRY) run flake8 --ignore=E231,E501,E712,E731,F401,W503 ./tests/ $(NAME) $(SYNC_NAME)
5757
$(POETRY) run mypy ./tests/ $(NAME) $(SYNC_NAME) --ignore-missing-imports --exclude migrate.py --exclude _compat\.py$
5858
$(POETRY) run bandit -r $(NAME) $(SYNC_NAME) -s B608
5959

aredis_om/model/model.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
AbstractSet,
1212
Any,
1313
Callable,
14+
ClassVar,
1415
Dict,
1516
List,
1617
Mapping,
@@ -32,7 +33,7 @@
3233
from ulid import ULID
3334

3435
from .. import redis
35-
from .._compat import BaseModel
36+
from .._compat import PYDANTIC_V2, BaseModel
3637
from .._compat import FieldInfo as PydanticFieldInfo
3738
from .._compat import (
3839
ModelField,
@@ -1419,13 +1420,22 @@ def outer_type_or_annotation(field):
14191420

14201421
class RedisModel(BaseModel, abc.ABC, metaclass=ModelMeta):
14211422
pk: Optional[str] = Field(default=None, primary_key=True)
1423+
ConfigDict: ClassVar
14221424

14231425
Meta = DefaultMeta
14241426

1425-
class Config:
1426-
orm_mode = True
1427-
arbitrary_types_allowed = True
1428-
extra = "allow"
1427+
if PYDANTIC_V2:
1428+
from pydantic import ConfigDict
1429+
1430+
model_config = ConfigDict(
1431+
from_attributes=True, arbitrary_types_allowed=True, extra="allow"
1432+
)
1433+
else:
1434+
1435+
class Config:
1436+
orm_mode = True
1437+
arbitrary_types_allowed = True
1438+
extra = "allow"
14291439

14301440
def __init__(__pydantic_self__, **data: Any) -> None:
14311441
__pydantic_self__.validate_primary_key()
@@ -1633,9 +1643,6 @@ def redisearch_schema(cls):
16331643

16341644
def check(self):
16351645
"""Run all validations."""
1636-
from pydantic.version import VERSION as PYDANTIC_VERSION
1637-
1638-
PYDANTIC_V2 = PYDANTIC_VERSION.startswith("2.")
16391646
if not PYDANTIC_V2:
16401647
*_, validation_error = validate_model(self.__class__, self.__dict__)
16411648
if validation_error:
@@ -1657,8 +1664,8 @@ def __init_subclass__(cls, **kwargs):
16571664
for typ in (Set, Mapping, List):
16581665
if isinstance(origin, type) and issubclass(origin, typ):
16591666
raise RedisModelError(
1660-
f"HashModels cannot index set, list,"
1661-
f" or mapping fields. Field: {name}"
1667+
f"HashModels cannot index set, list, "
1668+
f"or mapping fields. Field: {name}"
16621669
)
16631670
if isinstance(field_type, type) and issubclass(field_type, RedisModel):
16641671
raise RedisModelError(
@@ -1678,8 +1685,8 @@ def __init_subclass__(cls, **kwargs):
16781685
for typ in (Set, Mapping, List):
16791686
if issubclass(origin, typ):
16801687
raise RedisModelError(
1681-
f"HashModels cannot index set, list,"
1682-
f" or mapping fields. Field: {name}"
1688+
f"HashModels cannot index set, list, "
1689+
f"or mapping fields. Field: {name}"
16831690
)
16841691

16851692
if issubclass(outer_type, RedisModel):

docker-compose.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
version: "3.8"
2-
1+
---
32
services:
43
redis:
54
image: "redis/redis-stack:latest"

docs/models.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,11 @@ from redis_om import HashModel
142142
class Customer(HashModel):
143143
# ... Fields ...
144144

145-
class Config:
146-
orm_mode = True
147-
arbitrary_types_allowed = True
148-
extra = "allow"
145+
model_config = ConfigDict(
146+
from_attributes=True,
147+
arbitrary_types_allowed=True,
148+
extra="allow",
149+
)
149150
```
150151

151152
Some features may not work correctly if you change these settings.

tests/test_json_model.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -883,9 +883,23 @@ async def test_schema(m, key_prefix):
883883
# We need to build the key prefix because it will differ based on whether
884884
# these tests were copied into the tests_sync folder and unasynce'd.
885885
key_prefix = m.Member.make_key(m.Member._meta.primary_key_pattern.format(pk=""))
886-
assert (
887-
m.Member.redisearch_schema()
888-
== f"ON JSON PREFIX 1 {key_prefix} SCHEMA $.pk AS pk TAG SEPARATOR | $.first_name AS first_name TAG SEPARATOR | CASESENSITIVE $.last_name AS last_name TAG SEPARATOR | $.email AS email TAG SEPARATOR | $.age AS age NUMERIC $.bio AS bio TAG SEPARATOR | $.bio AS bio_fts TEXT $.address.pk AS address_pk TAG SEPARATOR | $.address.city AS address_city TAG SEPARATOR | $.address.postal_code AS address_postal_code TAG SEPARATOR | $.address.note.pk AS address_note_pk TAG SEPARATOR | $.address.note.description AS address_note_description TAG SEPARATOR | $.orders[*].pk AS orders_pk TAG SEPARATOR | $.orders[*].items[*].pk AS orders_items_pk TAG SEPARATOR | $.orders[*].items[*].name AS orders_items_name TAG SEPARATOR |"
886+
assert m.Member.redisearch_schema() == (
887+
f"ON JSON PREFIX 1 {key_prefix} SCHEMA "
888+
"$.pk AS pk TAG SEPARATOR | "
889+
"$.first_name AS first_name TAG SEPARATOR | CASESENSITIVE "
890+
"$.last_name AS last_name TAG SEPARATOR | "
891+
"$.email AS email TAG SEPARATOR | "
892+
"$.age AS age NUMERIC "
893+
"$.bio AS bio TAG SEPARATOR | "
894+
"$.bio AS bio_fts TEXT "
895+
"$.address.pk AS address_pk TAG SEPARATOR | "
896+
"$.address.city AS address_city TAG SEPARATOR | "
897+
"$.address.postal_code AS address_postal_code TAG SEPARATOR | "
898+
"$.address.note.pk AS address_note_pk TAG SEPARATOR | "
899+
"$.address.note.description AS address_note_description TAG SEPARATOR | "
900+
"$.orders[*].pk AS orders_pk TAG SEPARATOR | "
901+
"$.orders[*].items[*].pk AS orders_items_pk TAG SEPARATOR | "
902+
"$.orders[*].items[*].name AS orders_items_name TAG SEPARATOR |"
889903
)
890904

891905

0 commit comments

Comments
 (0)