redis-om-python icon indicating copy to clipboard operation
redis-om-python copied to clipboard

Pydantic v2 Incompatability with `strawberry-graphql`

Open XChikuX opened this issue 2 months ago • 3 comments

redis-om on version 0.3.0 with pydantic v2 raises this following error.

│ /root/test/.env/lib/python3.10/site-packages/strawberry/schema/schema_converter.py:777 in        │
│ from_type                                                                                        │
│                                                                                                  │
│   774 │   │   elif isinstance(type_, StrawberryObjectDefinition):                                │
│   775 │   │   │   return self.from_object(type_)                                                 │
│   776 │   │   elif isinstance(type_, StrawberryUnion):                                           │
│ ❱ 777 │   │   │   return self.from_union(type_)                                                  │
│   778 │   │   elif isinstance(type_, LazyType):                                                  │
│   779 │   │   │   return self.from_type(type_.resolve_type())                                    │
│   780 │   │   elif compat.is_scalar(                                                             │
│                                                                                                  │
│ ╭────────────────────────────────────────── locals ──────────────────────────────────────────╮   │
│ │  self = <strawberry.schema.schema_converter.GraphQLCoreConverter object at 0x7f0c5dabcd30> │   │
│ │ type_ = <strawberry.union.StrawberryUnion object at 0x7f0c5dadf190>                        │   │
│ ╰────────────────────────────────────────────────────────────────────────────────────────────╯   │
│                                                                                                  │
│ /root/test/.env/lib/python3.10/site-packages/strawberry/schema/schema_converter.py:795 in        │
│ from_union                                                                                       │
│                                                                                                  │
│   792 │   │   │   # TypeVars, Annotations, LazyTypes, etc it can't perfectly detect issues at    │
│   793 │   │   │   # that stage                                                                   │
│   794 │   │   │   if not StrawberryUnion.is_valid_union_type(type_):                             │
│ ❱ 795 │   │   │   │   raise InvalidUnionTypeError(union_name, type_, union_definition=union)     │
│   796 │   │                                                                                      │
│   797 │   │   # Don't reevaluate known types                                                     │
│   798 │   │   if union_name in self.type_map:                                                    │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │       self = <strawberry.schema.schema_converter.GraphQLCoreConverter object at              │ │
│ │              0x7f0c5dabcd30>                                                                 │ │
│ │      type_ = <class 'str'>                                                                   │ │
│ │      union = <strawberry.union.StrawberryUnion object at 0x7f0c5dadf190>                     │ │
│ │ union_name = "<class 'str'><class 'redis_om.model.model.ExpressionProxy'>"                   │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
InvalidUnionTypeError: Type `str` cannot be used in a GraphQL Union

I see this issue with HashModel JsonModel and EmbeddedJsonModel being used.

If I have an object with redis-om but its not part of the graphql schema then I only get the below warning

Running strawberry on http://0.0.0.0:8000/graphql 🍓
/root/test/.env/lib/python3.10/site-packages/pydantic/_internal/_config.py:334: UserWarning: Valid config keys have changed in V2:
* 'orm_mode' has been renamed to 'from_attributes'
  warnings.warn(message, UserWarning)

Using regular BaseModel from pydantic seems to work fine.

So I've triaged the issue to changes in redis-om

Has there been some kind of Union with str attached to JsonModel and EmbeddedJsonModel? I'd love to be able to resolve this issue.

XChikuX avatar May 03 '24 20:05 XChikuX

RedisModel (parent of JsonModel) has a pk field, which is declared as a Optional[str] but on the Model itself is a Union[str, ExpressionProxy]

slorello89 avatar May 06 '24 13:05 slorello89

RedisModel (parent of JsonModel) has a pk field, which is declared as a Optional[str] but on the Model itself is a Union[str, ExpressionProxy]

Is this a change in Pydantic v2 in redis-om 0.3.0. Or is it a regression in strawberry ?

XChikuX avatar May 06 '24 23:05 XChikuX

ExpressionProxy is what redis om uses to capture queries on the model e.g.

class A(JsonModel):
   name: str = Field(index=True)
   
a = await A.find(A.name == 'foo').first()

the type of A.name is an ExpressionProxy even if a.name is a str

I don't think this behavior is any different in v0.3.x vs v0.2.x

slorello89 avatar May 07 '24 14:05 slorello89