sopherapps / pydantic-redis

A simple Declarative ORM for Redis using pydantic Models
https://sopherapps.github.io/pydantic-redis
MIT License
39 stars 14 forks source link

Can't work with models that contain dicts of other models #11

Closed Tinitto closed 1 year ago

Tinitto commented 1 year ago

Currently a model like the ScoreBoard model below with the field scores being a dictionary of string and Model fails to work

from typing import Dict
from pydantic_redis import RedisConfig, Model, Store

class Score(Model):
    _primary_key_field: str = 'id'
    id: str
    total: int

class ScoreBoard(Model):
    _primary_key_field: str = 'id'
    id: str
    scores: Dict[str, Score]

if __name__ == '__main__':
    store = Store(name="test", redis_config=RedisConfig())
    store.redis_store.flushall()
    store.register_model(Score)
    store.register_model(ScoreBoard)

    example_score = Score(id="some id", total=50)

    ScoreBoard.insert(data=ScoreBoard(id='test', scores={"mark": example_score, "tom": example_score}))
    items = ScoreBoard.select(ids=["test"])
    print(f"{items}")

It raises the following exception:

Traceback (most recent call last):
  File "main.py", line 27, in <module>
    items = ScoreBoard.select(ids=["test"])
  File "/Users/apple.inc/work/code/sopherapps/pydantic-redis/pydantic_redis/model.py", line 139, in select
    return cls.__parse_model_list(response)
  File "/Users/apple.inc/work/code/sopherapps/pydantic-redis/pydantic_redis/model.py", line 237, in __parse_model_list
    return [cls(**record) for record in parsed_dict_list]
  File "/Users/apple.inc/work/code/sopherapps/pydantic-redis/pydantic_redis/model.py", line 237, in <listcomp>
    return [cls(**record) for record in parsed_dict_list]
  File "pydantic/main.py", line 342, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 2 validation errors for ScoreBoard
scores -> mark
  value is not a valid dict (type=type_error.dict)
scores -> tom
  value is not a valid dict (type=type_error.dict)

Pydantic_redis version: 0.1.6

Tinitto commented 1 year ago

It kind of seems like a dict might be better represented by a model

e.g.

class Score(Model):
    _primary_key_field: str = 'id'
    id: str
    total: int

class ScoreBoard(Model):
    _primary_key_field: str = 'id'
    id: str
    scores: Dict[str, Score]

might as well have been:

class Score(Model):
    _primary_key_field: str = 'name'
    name: str
    total: int

class ScoreBoard(Model):
    _primary_key_field: str = 'id'
    id: str
    scores: List[Score]