Closed
Description
I'm attempting to hash the password before save using Pydantic validators
sample Model code
from pydantic import BaseModel, Field
import datetime
from redis_om import (EmbeddedJsonModel, Field, JsonModel)
from pydantic import PositiveInt
from typing import Optional, List
from werkzeug.security import generate_password_hash, check_password_hash
from pydantic import validator
class User(JsonModel):
first_name: str = Field(index=True)
last_name: str = Field(index=True)
email: str = Field(index=True)
mobile: str = Field(index=True)
created_at: datetime.datetime = Field()
updated_at: datetime.datetime = Field()
timezone: Optional[str]
courses: set[CourseObj.pk] = Field(default=[])
meta: Optional[dict] = Field(default={})
password: str = Field()
status: str = Field()
role: str = Field() # admin, user
@validator('password', pre=True, always=True)
def hash_password(cls, password):
return generate_password_hash(password)
def to_json(self) -> dict:
return {
"id": self.pk,
"first_name": self.first_name,
"last_name": self.last_name,
"name": f"{self.first_name} {self.last_name}",
"email": self.email,
"mobile": self.mobile,
"created_at": self.created_at.strftime('%m-%d-%Y'),
"updated_at": self.updated_at.strftime('%m-%d-%Y'),
"timezone": self.timezone,
}
When I import my code it returns TypeError: cannot pickle 'classmethod' object
full stack
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/site-packages/redis_om/model/model.py", line 1205, in __new__
new_class = super().__new__(cls, name, bases, attrs, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/site-packages/pydantic/v1/main.py", line 221, in __new__
inferred = ModelField.infer(
^^^^^^^^^^^^^^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/site-packages/pydantic/v1/fields.py", line 506, in infer
return cls(
^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/site-packages/pydantic/v1/fields.py", line 436, in __init__
self.prepare()
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/site-packages/pydantic/v1/fields.py", line 546, in prepare
self._set_default_and_type()
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/site-packages/pydantic/v1/fields.py", line 570, in _set_default_and_type
default_value = self.get_default()
^^^^^^^^^^^^^^^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/site-packages/pydantic/v1/fields.py", line 439, in get_default
return smart_deepcopy(self.default) if self.default_factory is None else self.default_factory()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/site-packages/pydantic/v1/utils.py", line 693, in smart_deepcopy
return deepcopy(obj) # slowest way when we actually might need a deepcopy
^^^^^^^^^^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/copy.py", line 172, in deepcopy
y = _reconstruct(x, memo, *rv)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/copy.py", line 271, in _reconstruct
state = deepcopy(state, memo)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/copy.py", line 146, in deepcopy
y = copier(x, memo)
^^^^^^^^^^^^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/copy.py", line 231, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/chris/.pyenv/versions/3.11.2/lib/python3.11/copy.py", line 161, in deepcopy
rv = reductor(4)
^^^^^^^^^^^
TypeError: cannot pickle 'classmethod' object
When I change to to BaseModel the code works fine
class User(BaseModel):
first_name: str = Field(index=True)
last_name: str = Field(index=True)
....
Version details
pydantic==2.4.2
pydantic_core==2.10.1
redis==5.0.3
redis-om==0.2.2
Metadata
Metadata
Assignees
Labels
No labels